我编写了一个非常简单的单线程 Java 应用程序,它简单地迭代(几次)整数列表并计算总和。当我在我的 Linux 机器(Intel X5677 3.46GHz 四核)上运行它时,程序大约需要 5 秒才能完成。同时,如果我使用任务集将 jvm 限制为两个特定的内核(这是意料之中的,因为应用程序是单线程的,并且所有内核上的 cpu 负载 < 0.1%)。但是,当我将 jvm 限制为单核时,程序突然执行得非常慢,需要 350 多秒才能完成。我可以理解当 jvm 在主线程之外运行其他几个线程时,如果限制在单核上它只是稍微慢一点,但我无法理解这种极端差异。我在一台单核旧笔记本电脑上运行相同的程序,它执行了大约 15 秒。有没有人了解这里发生了什么,或者有没有人成功地将 jvm 限制为多核系统上的单核而没有遇到这样的事情? 顺便说一句,我在热点 1.6.0_26-b03 和 1.7.0-b147 上都试过了——同样的问题。
非常感谢
最佳答案
是的,这似乎违反直觉,但简单的解决方案是不这样做。让 JVM 使用 2 个内核。
FWIW,我的理论是 JVM 正在查看操作系统报告的内核数量,假设它将能够使用所有内核,并根据该假设调整自身。但是,您将 JVM 固定到单个内核的事实使得这种调整变得很糟糕。
一种可能是 JVM 开启了自旋锁。这是一种策略,其中不能立即获取锁的线程将“自旋”(反复测试锁)一段时间,而不是立即重新安排。如果您有多个核心并且锁持有时间很短,这会很好地工作,但如果只有一个核心可用,那么自旋锁是一种反优化。
(如果这是问题的真正原因,我相信您可以设置一个 JVM 选项来关闭自旋锁。)
关于固定到单个内核时,Java 应用程序/JVM 运行速度极慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10003951/