Java CMS GC行为

Java CMS GC行为,java,garbage-collection,Java,Garbage Collection,我有一个导致创建大量垃圾的应用程序。第一个(也是几乎一个)标准是低GC暂停时间。我使用visualgc工具(和GC日志)尝试不同的GC参数。最佳参数如下 -XX:+UseConMarkSweepGC -Xmx1172M -Xms600M -XX:+UseParNewGC -XX:NewSize=150M 我的应用程序使用Java 1.6.0_21在SunOS 10上运行。硬件是2个CPU四核(uname-x结果是numCPU=8) 问题是 观察GC行为,在伊甸园空间创建新对象,直到伊甸园满为止。

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

-XX:+UseConMarkSweepGC

-Xmx1172M

-Xms600M

-XX:+UseParNewGC

-XX:NewSize=150M

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

问题是

观察GC行为,在伊甸园空间创建新对象,直到伊甸园满为止。当eden space full GC运行时,清除垃圾,如果对象不是死拷贝到旧gen(我丢弃“from”&“to”spaces),同样,旧gen已满,GC使用CMS并发阶段运行,并清除旧gen空间。CMS的某些部分是停止世界(暂停时间)。这是一个循环

  • 这是真的吗
  • GC清理旧gen空间后,没有足够的空间扩展旧gen空间(XMS和XMS值不同)
  • 完全GC操作何时开始?如何决定
  • CMS并发阶段持续时间取决于Eden空间的大小,实际上我的期望是,Eden空间不会影响CMS并发阶段持续时间。在CMS并发阶段,与伊甸园空间相关的GC正在进行什么
  • 还有什么建议可以让我尽量减少暂停时间?事实上,对我来说最有价值的答案是:)

  • 谢谢

    最小化GC影响的最佳方法是减少创建的对象数量。总的来说,这并不总是容易做到或是最好的解决方案,但它将最小化GC暂停

    如果无法生成更少的对象,请尝试使它们足够短暂,并且使伊甸园空间足够大,使它们不会离开伊甸园空间。(或使产品寿命很长并重复使用)

  • 这里有三个空间需要担心,伊甸园->幸存者->终身监禁

  • GC尝试确保在完全GC后有足够的可用空间,
    -ms
    -mx
    选项控制它们的大小(以前称为
    -Xms
    -Xmx

  • 当永久空间已满,或suvivor空间已耗尽(例如,从eden空间复制的对象太多)或CMS desices现在是尝试并同时进行清理的好方法时,完整GC开始

  • CMS仅清理永久空间

  • 见我以前的答案


  • 在使用CMS时,你不能忽略幸存者空格。CMS不是压缩收集器,这意味着如果您(或JVM)获取的持续时间阈值错误,则您将缓慢地将对象释放到持续时间中,这将增加持续时间碎片的速率,这将在强制CMS时提前时间,因为它没有足够的连续可用空间来处理从幸存者空间提升到持续时间中的操作,这将强制执行完整的gc循环没有预先警告,因此这是1 STW暂停中的全部内容。这需要多长时间取决于堆的大小,但有一点很可能是,它比普通的eden集合要长几个数量级

    这里还有几件事需要注意

  • STW暂停不仅来自CMS,还来自年轻一代的收集器
  • CMS有2个STW阶段(标记和备注)和3-4个并发阶段,第一个STW阶段(标记)是严格的单线程,可能会导致问题(关于此的示例讨论)
  • 您可以控制处理并发阶段的线程数
  • 您需要了解对象的寿命,这可能意味着使用
    -XX:+PrintTenuringDistribution
    ,或者您可以像以前一样使用visualgc进行观察
  • 然后,您可以使用
    -XX:SurvivorRatio
    对此进行调整,以控制相对于eden的幸存者空间的大小,并使用
    -XX:MaxTenuringThreshold
    控制对象在年轻集合中存活的频率,然后再将其保留
  • -XX:CMSInitiatingOccupancyFraction
    可用于指导CMS在开始CMS阶段之前需要多满(如果这个错误,您将严重暂停)
  • 最终,您需要了解哪个采集器正在暂停,暂停的频率,暂停的时间,以及暂停是否有任何异常原因。然后,您需要将其与每一代的大小进行比较,以查看是否可以调整参数以最小化暂停的数量(和/或持续时间)

    请记住,这可能是由于需要进行长时间运行的测试,以查看它是否会随着时间的推移而恶化。同样,如果没有一个可重复的、自动化的工作负载,就几乎不可能得出任何关于您是否确实改进了工作的明确结论


    一个很好的内部总结信息来源是。另一个很好的演示是。

    我同意您关于增加eden空间决策的看法。我已经尝试了不同的newSize参数,并从gc日志中检查暂停时间,该行包括“重新扫描”。“新闻大小”值越小,暂停时间越短。3个不同的newSize值与我的推断是平行的。20小时后,gc记录了大约5次完整gc运行,我猜运行完整gc的一些线索是“升级失败”和“并发模式失败”。在谷歌上搜索这些原因。很快,增加“升级失败”的旧代大小,并为“并发模式失败”设置最小值XX:cmSinitiatingOccupencyFraction。我将尝试设置XX:CMSInitiatingOccupancyFraction小值(如30或60)并增加堆。我将分享测试结果。升级失败通常是我提到的碎片问题,它强制执行非并发完整gc。您需要检查您的寿命阈值并适当调整其大小。将初始占用率设置为一个较低的值(默认值为70 iirc)只会意味着更频繁的完整地面军事系统,这不会带来太多的好处。你有很多东西可以活很长时间吗?你可能会发现一个巨大的伊甸园和一个小小的终身监禁是一个不错的选择