0

我编写了一个非常简单的单线程 java 应用程序,它简单地迭代(几次) Integer:s 列表并计算总和。当我在我的 Linux 机器(Intel X5677 3.46GHz 四核)上运行它时,程序大约需要 5 秒才能完成。同时,如果我使用任务集将 jvm 限制为两个特定的内核(这是完全可以预料的,因为应用程序是单线程的,并且所有内核上的 cpu 负载<0.1%)。但是,当我将 jvm 限制为单核时,程序突然执行异常缓慢,需要 350 多秒才能完成。我可以理解,当 jvm 除了主线程之外还运行其他几个线程时,它是否只是在限制为单个内核时稍微慢一些,但我无法理解这种极端差异。我在一台单核的旧笔记本电脑上运行相同的程序,它在大约 15 秒内执行。有谁知道这里发生了什么,或者有没有人成功地将 jvm 限制为多核系统上的单核而没有遇到类似的事情?顺便说一句,我用热点 1.6.0_26-b03 和 1.7.0-b147 都试过了——同样的问题。

非常感谢

4

2 回答 2

2

是的,这似乎违反直觉,但简单的解决方案是不这样做。让 JVM 使用 2 个内核。

FWIW,我的理论是 JVM 正在查看操作系统报告的内核数量,假设它将能够使用所有这些内核,并根据该假设进行自我调整。但是,您已将 JVM 固定到单个内核的事实使这种调整变得很糟糕。

一种可能性是 JVM 已打开自旋锁定。这是一种策略,其中无法立即获取锁的线程将“旋转”(反复测试锁)一段时间,而不是立即重新调度。如果您有多个核心并且锁被持有很短的时间,这可以很好地工作,但如果只有一个核心可用,那么自旋锁是一种反优化。

(如果这是问题的真正原因,我相信您可以设置一个 JVM 选项来关闭自旋锁。)

于 2012-04-04T02:02:40.487 回答
1

如果您有两个或多个相互依赖的线程,这将是正常行为。想象一个程序,其中两个线程在它们之间乒乓球消息或数据。当它们都在运行时,每个乒乓球可能需要 10 - 100 ns。当它们必须进行上下文切换才能运行时,它们可能需要 10 - 100 微秒。增加 1000 倍我不会感到惊讶。

如果您想将程序限制在一个核心上,您可能需要重新编写它的一部分,以便将其设计为在一个核心上有效地运行。

于 2012-04-04T06:24:02.047 回答