2011-03-16 56 views
6

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

-XX:+ UseConcMarkSweepGC

-Xmx1172M

-Xms600M

-XX:+ UseParNewGC

-XX:新尺寸= 150M

我的申请使用Java 1.6.0_21在SunOS 10上运行。硬件是2个CPU四核(uname -X结果是numCPU = 8)。

问题是

观察GC行为,新创建的对象上伊甸园空间,直到伊甸园已满。当伊甸园空间完整的GC运行时,清除垃圾,如果对象没有死亡复制到旧版本(我'丢弃'从'&'到'空格),类似的旧版本已满,GC运行CMS并发阶段并清除旧的-gen空间。 CMS的某些部分是停止世界(暂停时间)。这是一个循环。

  1. 以上scenerio是真的吗?
  2. GC清理旧版空间后,没有足够的空间扩展旧版空间(XMS和XMS值不同)?
  3. 完整的GC操作何时开始?如何决定?
  4. CMS并发阶段持续时间取决于伊甸园空间大小,实际上我的预期是,伊甸园空间不影响CMS并发阶段持续时间。与CMS-并发阶段上的eden空间相关的GC发生了什么?
  5. 还有什么建议我最大限度地减少暂停时间?事实上,我觉得最有价值的答案:)

感谢

回答

10

您不能忽略使用CMS时的生存空间。 CMS不是一个压缩收集器,这意味着如果你(或JVM)获得了错误的持续时间门槛,那么你将慢慢地将对象放入终身,这将增加终止片段的速度,这将导致CMS被强制的时间,因为它没有足够的连续可用空间可用于处理来自幸存者空间的促销活动,从而在没有预先警告的情况下强制执行完整的gc循环,因此这是1 STW暂停时的全部内容。这需要多长时间取决于你的堆的大小,但有一件事情很可能,它会比正常的伊甸园收藏时间长数倍。

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

  1. STW暂停并不仅仅来自CMS,他们来自年轻代收集太
  2. CMS有2个STW阶段(标记,备注)和3-4并发阶段,第一阶段STW(马克)严格单线程这可能会导致问题
  3. 您可以控制没有线程处理并发阶段
  4. 您需要了解对象是如何长的寿命一般为(在此here样本的讨论),这可能意味着使用-XX:+PrintTenuringDistribution或你可以像你做的那样用visualgc来观看它
  5. 然后,您可以调整这个与-XX:SurvivorRatio控制相对生存空间的大小伊甸园-XX:MaxTenuringThreshold来控制它的终身
  6. -XX:CMSInitiatingOccupancyFraction前一个对象可以多久生存的一个年轻的集合,可用于指导CMS至于如何全它需要开始之前CMS阶段(得到这个错误,你会暂停严重)

最终你需要了解哪些收集器暂停,有多久,多久以及是否有任何异常暂停的原因。然后,您需要将其与每一代的大小进行比较,以查看是否可以调整参数以最大限度地减少暂停的次数(和/或持续时间)。

请记住,由于需要长时间运行测试以确定它是否会随着时间的推移而恶化,因此可能会造成时间缩短。此外,如果没有可重复的自动化工作负载,几乎无法得出关于您是否真正改进了事情的确切结论。

内部总结信息的一个很好的来源是Jon Masamitsu's blog。另一个很好的介绍是GC Tuning in the HotSpot Java VM

+0

经过20个小时,gc记录了大约5倍的完整gc运行,我猜想一些线索为什么运行Full GC是“升级失败”和“并发模式失败”。在google上搜索这些原因。稍后,为“促销失败”增加旧一代大小,并为“并发模式失败”设置最小值XX:CMSInitiatingOccupancyFraction。我会尝试设置XX:CMSInitiatingOccupancyFraction小值(如30或60)并增加堆。我会分享测试结果。 – 2011-03-17 09:59:23

+0

促销失败通常是我提到的碎片问题,它强制一个非并发的完整gc。你需要检查你的持续时间门槛并适当调整他们的大小。将初始占用设置为较低值(默认值为70 iirc)意味着更频繁的完整gcs,这些gcs不会做太多,这并不好。你甚至有很多这样的生活很长一段时间?你可能会发现一个巨大的伊甸园,一个小的终身制是一个不错的选择。 – Matt 2011-03-17 10:09:36

+0

较低的启动占用值是CMS更常见的,但没有问题。最大的问题STW,而2-3秒。吞吐量或0.0x秒STW对我来说不是问题。我已经尝试过大的伊甸园大小,但是STW的持续时间增加了:(如何设置并发阶段的线程数? – 2011-03-17 12:03:38

2

,以尽量减少GC的影响,最好的办法是minise你创建对象的对象的数量。这并不总是很容易做到或总体上最好的解决方案,但它会减少GC暂停。

如果你不能生产更少的物品,尽量让它们足够短暂,足够大的伊甸园空间不要离开伊甸园的空间。 (或做很长的生活和再利用)

  1. 有三个空格担心这里,伊甸 - >幸存者 - >终身http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html

  2. 的GC努力,以确保有足够的自由一个完整的GC后空间和-ms-mx选项做控制,他们将有多大(前者素有-Xms-Xmx

  3. 当终身空间已满,或suvivor空间枯竭型全GC启动(例如,有o从eden空间复制的许多对象)或者CMS desices现在是尝试并行清理的一个很好的方面。

  4. CMS只清理终身空间。

  5. 查看我以前的答案。

+0

我同意你关于增加伊甸园空间的决定。我已经尝试了不同的newSize参数,并检查从gc日志中暂停时间该行包括“重新扫描”。更少的newSize值导致更少的暂停时间。我的推论中有3个不同的newSize值是平行的。 – 2011-03-16 09:17:24