0
点赞
收藏
分享

微信扫一扫

CMS调优方向

静鸡鸡的JC 2021-09-24 阅读 87
日记本

一、[ParNew (promotion failed): ...

这种情况就是单纯出现了promotion failed,此时cms未执行并发收集
二、concurrent mode failure): ...

这种情况是单纯的cms正在执行并发收集,然后用户线程申请内存空间不足
三、 [ParNew (promotion failed): ... (concurrent mode failure):...

这种情况是先出现了promotion failed,然后准备触发fgc

而此时cms这在执行并发收集,此时则执行打断逻辑,输出concurrent mode failure

具体源代码也是concurrentMarkSweepGeneration.cpp

四、promotion failed

  1. Java Performance,The Definitive Guide的原文是这样描述的:
    • Here, CMS started a young collection and assumed that there was enough free space to hold all the promoted objects (otherwise, it would have declared a concurrent mode failure). That assumption proved incorrect: CMS couldn’t promote the objects because the old generation was fragmented (or, much less likely, because the amount of memory to be promoted was bigger than CMS expected).
    • 翻译:新生代垃圾收集,判断老年代似乎有足够的空闲空间可以容纳所有的晋升对象(否则,CMS收集器会报concurrent mode failure)。这个假设最终被证明是错误的,由于老年代空间的碎片化(或者,不太贴切的说,由于晋升实际要占用的内存超过了CMS收集器的判断),CMS收集器无法晋升这些对象。
  2. Sometimes we see these promotion failures even when thelogs show that there is enough free space in tenured generation. The reason is'fragmentation' - the free space available in tenured generation is notcontiguous, and promotions from young generation require a contiguous freeblock to be available in tenured generation. CMS collector is a non-compactingcollector, so can cause fragmentation of space for some type of applications.
    • 翻译:CMS收集器对老年代收集的时候,不再进行任何压缩和整理的工作,意味着老年代随着应用的运行会变得碎片化;碎片过多会影响大对象的分配,虽然老年代还有很大的剩余空间,但是没有连续的空间来分配大对象
  3. 如果在ParNew准备收集时CMS说晋升没问题,但ParNew已经开始收集之后确实遇到了晋升失败的情况
  4. promotion failed是说,担保机制确定老年代是否有足够的空间容纳新来的对象,如果担保机制说有,但是真正分配的时候发现由于碎片导致找不到连续的空间而失败;而concurrent mode failure是指并发周期还没执行完,用户线程就来请求比预留空间更大的空间了,即后台线程的收集没有赶上应用线程的分配速度。
  5. promotion failed触发fgc,触发模式同上,通常也是Serial Old GC

五、并发模式失败(Concurrent mode failure)

  1. 在cms并发周期执行期间,用户的线程依然在运行,如果这时候如果应用线程向老年代请求分配的空间超过预留的空间,就会抛出该错误 - 后台线程的收集没有赶上应用线程的分配速度
  2. 有时候“空间不足”是CMS GC时当前的浮动垃圾过多导致暂时性的空间不足,而浮动垃圾就是cms执行期间用户线程申请的内存空间
  3. 这个错误可能触发两种情况
  1. 所以通常来说不建议设置上面两个参数,否则可能在Java8中会触发foreground collector,可能会更慢(单线程)。所以通常当出现concurrent mode failure时触发的都是Serial Old GC
举报

相关推荐

0 条评论