Java CMS GC行为

Erd*_*kın 6 java garbage-collection

我有一个导致创建大量垃圾的应用程序.第一个(和几乎一个)标准是低GC暂停时间.我使用visualgc工具(和gc日志)尝试不同的GC参数.最佳参数如下.

-XX:+ UseConcMarkSweepGC

-Xmx1172M

-Xms600M

-XX:+ UseParNewGC

-XX:新尺寸= 150M

我的应用程序在带有Java 1.6.0_21的SunOS 10上运行.硬件是2 x CPU四核(uname -X结果是numCPU = 8).

问题是

观察GC行为,在伊甸园空间上创建新对象,直到伊甸园已满.当eden space full GC运行时,清除垃圾,如果对象不是死复制到Old-gen(我丢弃'从'&'到'空格),同样Old-Gen已满,GC运行与CMS并发阶段并清除旧-gen空间.CMS的某些部分是Stop-the-world(暂停时间).这是一个循环.

  1. 以上场景是真的吗?
  2. 在GC清理旧的gen空间后,没有足够的空间扩展旧的gen空间(XMS和XMS值不同)?
  3. 完全GC操作开始时?怎么决定呢?
  4. CMS并发阶段持续时间取决于Eden空间大小,实际上我的期望是,Eden空间不会影响CMS并发阶段持续时间.GC与CMS并发阶段的eden空间有什么关系?
  5. 还有什么建议我最小化暂停时间?的确,对我来说最有价值的答案:)

谢谢

Mat*_*att 10

使用CMS时,您不能忽略幸存者空间.CMS不是一个压缩收集器,这意味着如果你(或者JVM)得到了错误的终点,那么你将慢慢地将对象放到tenured中,这会增加tenured片段的速率,这将提升CMS被强制的时间,因为它没有足够的连续可用空间来处理从幸存者空间到终身房的促销,这将迫使完整的gc循环没有预先警告,因此在1 STW暂停中是完整的.这需要多长时间取决于堆的大小,但有一件事很有可能,它将比普通的伊甸园集合长几个数量级.

这里还有一些其他注意事项;

  1. STW暂停不仅来自CMS,它们也来自年轻的收藏家
  2. CMS有2个STW阶段(标记和备注)和3-4个并发阶段,第1个STW阶段(标记)是严格单线程的,这可能会导致问题(这里的示例讨论)
  3. 您可以控制处理并发阶段的线程数
  4. 您需要了解对象的生存时间,这可能意味着使用-XX:+PrintTenuringDistribution或者您可以像使用visualgc一样观看它
  5. 然后,您可以调整它-XX:SurvivorRatio以控制相对于伊甸园的幸存者空间的大小,并-XX:MaxTenuringThreshold控制对象在年终集合生存之前能够存活的频率
  6. -XX:CMSInitiatingOccupancyFraction 可用于指导CMS在启动CMS阶段之前需要多长时间(出错并且你会暂停)

最终,您需要了解哪个收集器正在暂停,多长时间,多长时间以及该暂停是否有任何异常原因.然后,您需要将其与每代的大小进行比较,以查看是否可以调整参数以最小化暂停的数量(和/或持续时间).

请记住,由于需要长时间运行测试以确定它是否会随着时间的推移而恶化,因此可能会出现这种情况.在没有可重复的自动化工作负载的情况下,几乎不可能得出关于您是否真正改进了事物的任何确切结论.

内部摘要信息的一个很好的来源是Jon Masamitsu的博客.另一个很好的演示文稿是HotSpot Java VM中的GC调优.