固定到单个内核时,Java 应用程序/JVM 运行速度极慢

标签 java linux

我编写了一个非常简单的单线程 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/

相关文章:

java - 如何将网格中单元格的邻居存储到优先级队列中

linux - 打印 'find' linux 命令找到匹配项的目录

c++ - 如何让我的 `std::string url_encode_wstring(const std::wstring &input)` 在 Linux 上工作?

linux - Linux 下的 Live DVD 刻录

Java 输入流读取缓冲区

java - 如何在客户端散列 JAAS j_password?

java - Spring 的 ORM(hibernate)与 hibernate

java - 如何为基于TDD的方法编写负面测试?

linux - 我在哪里可以获得 Psiphon 源代码以及如何在 CentOS 5 上编译它?

python - '!<' 过滤 Pandas 的语法错误