我正在升级生产硬件,我们发现与旧套件相比,新套件上的新生代 GC 数量要多得多。
相同的程序(相同的二进制文件)在两台机器上运行。一个明显的区别(我希望这不会对 JVM 产生影响)是我们升级了 RHEL5 -> RHEL6。
我们的 JVM(Java 64 位 Hotspot 1.6,两者上的 java -version
相同)使用相同的命令行 GC 选项运行:
-XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+UseParallelGC -XX:+UseCompressedOops
还有:
-Xmx1024M -Xms1024M -XX:NewSize=512M -XX:SurvivorRatio=2
机器之间的区别在于新机器具有大约两倍的 RAM(32gb
- 尽管最大堆没有变化)和更多的内核(24 对 16)。
应用程序本身连接到多个外部进程并执行大量网络操作 - 因此这可能表明某些回归、错误配置或不兼容(这就是我们测试的原因...)。我想知道的是:
新生代 GC 水平的提高是否可能是在更多内核上运行的自然和预期结果,或者我应该关注这种发展?
我们在 JConsole 中确认了 GC 的数量,但这与做的差不多:
grep "PSYoungGen" ./log | wc -l
(注意 -XX:+PrintGC -XX:+PrintGCDetails
)
Full GC 在两个盒子上看起来差不多。
请注意,这是整个应用程序启动过程中的 GC 次数 - 因此它不会执行“更多工作”。这是相同的工作,只是运行了更多的 GC。
例如,我想知道 -XX:+UseParallelGC
是否会导致日志中出现更多条目,因为正在使用更多线程(将年轻代集合切成更小的部分,这意味着更多、更小的集合 - 无需担心)。
最佳答案
令人费解的问题...
简答
不,GC 频率只是您的创建率的函数。除非您的应用程序利用这个新硬件,否则 GC 频率应该相同。
长答案
我不认为这与操作系统升级有关,我也不认为总 RAM 的增加与此有关。
它不能来自指针大小的增加,因为最大堆大小为 1GB。所以 JVM 已经使用 32 位指针,即使您在 64 位 JVM 上也是如此。
您的应用程序是否在启动期间使用了所有内核?
这可以解释 YoungGC 速率的增加:如果您的应用程序使用 8 个以上的线程,这意味着它将在相同的时间内执行更多的工作。您应该观察到分配率的增加(请参阅您的 GC 日志)。
您还应该注意到 Young GC 持续时间的减少,因为 PSScavenge 使用更多线程。这是正确的吗?
根据 this page , ParallelGCThreads = (ncpus <= 8) ? ncpus : 3 + ((ncpus * 5) / 8)
.您在一个 YGC 周期中使用了 13 个线程,现在使用了 18 个。
关于java - 增加可用内核和 RAM 的数量是否会导致 JVM 执行更多的 GC?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16589858/