【发布时间】:2016-03-25 10:43:05
【问题描述】:
在一个中等繁忙的生产服务器(50 个应用线程,30% 的 CPU 利用率)上,我们看到 CMS 收集器跟不上提升到老一代的对象的速度。
我最初的想法是这些对象显然仍然被引用,因此不符合收集条件 - 但是当 Old Gen 填充并提示串行收集时,6 GiB 中的 5.5 GiB 被回收。
Eden 空间大小为 3 GiB,大约需要 20 到 30 秒才能填满足够提示年轻集合的空间。幸存者空间使用量在 800 - 1250 MiB 之间波动,最大 1.5 GiB(每个)。
由于旧代中的对象符合收集条件,并且服务器具有大量(明显)资源,我不明白为什么 CMS 收集器不能保持旧代大小:
什么可能导致这种情况,有什么解决办法吗?
我知道占用率,但我不明白 CMSIncrementalSafetyFactor 的含义 - 我已经阅读了一些 Oracle 文档,但我不知道在计算工作周期”实际上意味着..?
替代品
切换到并行/吞吐量收集器会产生非常低的 GC 开销 (1.8%),但偶尔会出现(每天 50 次)长时间停顿 - 每次完整 GC 大约 20 秒。即使进行了一些调整,这也不太可能达到我们的最大暂停目标。
在理想情况下,我们可以试验 G1 收集器,但由于各种原因,我们只能使用 Java 6 JVM。
【问题讨论】:
-
查看 GC 日志事件的输出可以让您更深入地了解。
-
@MarkoTopolnik 有什么我应该寻找的特定事件吗?我查看了日志,但没有任何异常(在我看来)。
-
我希望所有 CMS 相变事件的时间和实际收集的数量应该比现在提出的问题更清晰。
标签: java garbage-collection concurrent-mark-sweep