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