尽管有很多自由堆,GC仍然一直在旋转

时间:2014-07-14 16:51:56

标签: java garbage-collection

我有一个运行-mx7000m的应用程序。我可以看到它分配了5.5 GB的堆。然而由于某些原因,它不断地进行GCing,而且这就是CMS,结果证明它非常占用CPU。因此,它已经分配了5.5 GB的堆,但不知何故,它花费了所有的CPU时间来尝试保持使用的堆尽可能小,大约2 GB - 而另一个3.5G由JVM分配但未使用。

我有一些配置完全相同的服务器,5个中有2个以这种方式运行。有什么可以解释的?

它是Java 6,标志是:-server -XX:+PrintGCDateStamps -Duser.timezone=America/Chicago -Djava.awt.headless=true -Djava.io.tmpdir=/whatever -Xloggc:logs/gc.log -XX:+PrintGCDetails -mx7000m -XX:MaxPermSize=256m -XX:+UseConcMarkSweepGC

1 个答案:

答案 0 :(得分:0)

触发CMS GC的默认阈值为70%已满(在Java 6中)。根据经验,堆大小应该是完整GC之后使用的堆的2.5倍(但是您的用例可能不同)

所以在你的情况下,说你有

- 2.5 GB of young generation space
- 3 GB of tenured space.

当您的终身空间达到70%或~2.1GB时,它将开始清理该地区。

涉及的设置是-XX:CMSInitiatingOccupancyFraction=70

但是,如果您想减少GC的影响,最简单的方法就是减少垃圾。即使用内存分析器并确保分配率尽可能低。如果您创建的垃圾与CPU可以处理100 MB / s或1 MB / s或更低的垃圾一样,您的系统将会运行非常不同。

由于区域的相对大小可能不同,您可能有不同的服务器运行的原因可能不同,比如你有0.5年轻和5.0 GB的终身,你不应该看到这一点。差异可能完全取决于您启动流程时机器的繁忙程度或者此后的工作情况。