JVM回收器日志中 Promotion Failed 含义

作者:技术拾光

时间:2026-07-12

浏览:519

晋升失败(PromotionFailed)并非老年代空间不足,而是因碎片化缺乏连续内存块,常见于CMS等无压缩回收器。大对象晋升需整块分配,即便总空间充裕,也会因碎片化失败而触发FullGC,导致停顿时间显著延长。

文章目录

在JVM调优实践中,一个常见现象令人困惑:老年代明明还有剩余空间,Minor GC却报出Promotion Failed。问题根源不在于总量,而在于碎片化。

Promotion Failed的本质是什么

JVM回收器日志中 Promotion Failed 含义

Promotion Failed的直接含义是:年轻代对象在Minor GC后无法顺利晋升到老年代。但请注意,这并不等同于老年代已经“满了”。真实原因是老年代中缺乏足够大的连续空闲内存块来容纳这批待晋升的对象。

为什么老年代内存碎片会导致晋升失败

这个问题在CMS或Parallel Old这类不带压缩能力的回收器上尤为常见。CMS采用“标记-清除”算法,清理后内存天然就是碎片化的。假设一个几百KB甚至几MB的大对象——比如大数组、长字符串或缓存块——需要晋升,它必须整块分配,无法拆分。此时,即便老年代总剩余空间有2GB,只要最大连续空闲块只有300KB,晋升就会失败。

如何从日志中识别Promotion Failed

日志中的信号非常典型,一看便知:

  • [ParNew (promotion failed): 146112K->146112K(153600K), 0.2255230 secs]
    年轻代使用量几乎不变,说明GC根本没回收出空间,所有对象都卡在Eden或Survivor区,等待晋升却无法进入老年代。
  • 紧接着,日志里会出现[Full GC ...]
    JVM启动兜底机制,退化为Stop-The-World的串行或并行Full GC,停顿时间显著拉长。
  • 如果用的是CMS,常伴随CMS-concurrent-mark (concurrent mode failure)
    晋升失败导致老年代瞬间失守,CMS还没来得及完成并发标记就被迫中止,转而执行代价更高的Full GC。

Promotion Failed的本质:内存碎片与大对象集中晋升

因此,Promotion Failed不是单纯的“内存不够”,而是“内存够,但拼不出一块整地”。其本质是老年代碎片化与大对象集中晋升共同作用的结果。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章