什么时候有人在多核机器上使用CMS垃圾收集器的单个线程?

时间:2016-02-13 16:32:45

标签: java performance concurrent-mark-sweep

我在使用Java 7 JVM的服务器上运行Apache Storm拓扑。我一直在考虑一些JVM调优,并注意到它目前正在使用并发标记和扫描(CMS)垃圾收集器。这是有道理的,因为服务器有32个内核,并且在使用此设置运行多个JVM时,它只运行4个这样的JVM,其少于32个内核。

但是,我注意到我们正在运行垃圾收集器,设置为CMSConcurrentMTEnabled 关闭。默认情况下,该设置将 on ,这让我想知道为什么有人会在其他线程可用时选择使用单个线程进行并发垃圾收集。在什么条件下使用该设置是有意义的,假设其他线程可用?

(编辑有关我目前情况的更多细节,希望能够得到答案):

JVM似乎耗尽内存,重复执行次要GC,每次耗时约9秒,最终崩溃。没有OutOfMemoryError被抛出,这令我感到困惑。次要GC每次清理几个kB,整体使用率在很长一段时间内徘徊在100%左右。堆大小为4 GB,因此这些条件应触发OutOfMemoryError。然而,我担心这会引发SO问题的非常局部化的情况。

2 个答案:

答案 0 :(得分:2)

所以,根据Twitter的专家和一些邮件列表,Java 6更新21中存在一个错误

  

... CMS不会总是释放带终结器的对象[。]

修复方法是禁用设置CMSConcurrentMTEnabled。 (或者使用较新版本的Java。)我不确定哪个版本的Java是第一个解决此问题的版本。

答案 1 :(得分:0)

修改

在多核计算机上使用单个线程不会使用计算机的全部功能。

如果要增加CMS的并行gc线程数,可以使用以下配置。

可以使用命令行选项-XX控制垃圾收集器线程的数量:ParallelGCThreads =。

可以在documentation文章中找到更多微调选项。

考虑使用G1GC代替CMS。

G1GC 在JDK 7 update 4发布后的大堆中变得非常流行。它可能成为Java 9版本中的默认GC算法。

通过设置暂停时间目标等目标,可以提高暂停时间的可预测性。

看看

http://www.oracle.com/technetwork/articles/java/g1gc-1984535.html

http://www.oracle.com/technetwork/tutorials/tutorials-1876574.html