群内关于CMS垃圾回收失败是不是进行FULL GC问题的记录

背景

最近关注了两篇文章
群友阿杜写的 CMS学习笔记
群友阿飞写的 CMS几种GC模式解读-感谢你假笨的指正

可能阿杜写的早的那篇我看过,当时就有疑问,后来他也在文章补录里面补充了下垃圾回收失败后由于不同的原因是否进行FULL GC,你可以对着这两篇文章补充着看,相信你的认识会更深刻一些。

下面贴聊天记录:

我:@深圳-Javaer-阿飞 请教个问题白
阿飞:??
我:我找下那个文章哈 稍等 CMS学习笔记
阿飞:阿杜的文章 怎么?
我:并发模式失败到底引不引起full gc
我:我组织下语言哈
我:并发模式失败(Concurrent mode failure):CMS的目标就是在回收老年代对象的时候不要停止全部应用线程,在并发周期执行期间,用户的线程依然在运行,如果这时候如果应用线程向老年代请求分配的空间超过预留的空间(担保失败),就回触发concurrent mode failure,然后CMS的并发周期就会被一次Full GC代替
我:这里他说 如果并发模式失败会引起一次full gc
我:但是他下面调优的时候说
我:(4)Serial-Old收集老年代的停顿;
我:其中并发模式失败会导致第(4)种情况,晋升失败和永久代空间耗尽会导致第(5)种情况。
我:意思是并发模式失败会用Serial-Old收集老年代
我:如果是单纯的收集老年代的话还是full gc吗?
我:我的疑问是 如果是并发担保失败 是不是就升级成Serial-Old垃圾回收器 stop the world 去收集整个老年代 ,如果是这样 是不是就不应该称为full gc了
我:原来看你们说的 只要是full gc 应该是把年轻代 永久代 老年代 都回收了
「北京-张百音:原来看你们说的 只要是full gc 应该是把年轻代 永久代 老年代 都回收了 」
- - - - - - - - - - - - - - -
这个是R大说的

image.png
阿飞:「北京-张百音:我的疑问是 如果是并发担保失败 是不是就升级成Serial-Old垃圾回收器 stop the world 去收集整个老年代 ,如果是这样 是不是就不应该称为full gc了 」
- - - - - - - - - - - - - - -
并发模式失败,应该要说退化成serial gc模式
阿飞:这个时候采用的是MSC算法
我:嗯 嗯
阿飞:The G1 garbage collector is designed to avoid full collections, but when the concurrent collections can't reclaim memory fast enough a fall back full GC will occur. The current implementation of the full GC for G1 uses a single threaded mark-sweep-compact algorithm.
阿飞:G1和cms的full gc是一样的
阿飞:这段英文来自: https://openjdk.java.net/jeps/307
阿飞:JDK10改成并行了
我:得 学无止境 。。。。
我:在问一个小问题
我:你们讨论的这个
我:执行的时候看这两个参数的设置 是否进行内存压缩白
我:意思就是再concurrent mode failure触发的foreground模式下 如果设置压缩 才会执行压缩算法 如果不设置 只不过是一个长的暂停 标记清理 这么理解对吗?
阿飞:事实上,我看源码,这块逻辑是这样的。 根据这三个条件判断是否需要压缩,压缩的话走msc,不压缩的话,走省略了并发阶段的cms(笨神说的foreground cms gc)
我:嗯呢 我突然响起来你写过这个文章 我去在撸撸
阿飞:但是无论走msc,还是foreground gc,都是完全STW的
我:嗯呢 https://www.jianshu.com/p/be5389ca93f7 这个是吧
阿飞:嗯嗯
阿飞:这个是不压缩的逻辑,最后调用collect_in_foreground,就是省略了并发阶段的cms, 即foreground cms gc
我:Foregroud 模式相当于省略了cms的一堆步骤 直接去做标记清理 以便于让垃圾回收器回收资源 供用户线程使用白
阿飞:是的,因为反正并发模式搞不定了,
我:ok 好的 非常感谢
阿飞:省略了哪些步骤,你如果敢兴趣,自己去看一下hotspot\src\share\vm\gc_implementation\concurrentMarkSweep\concurrentMarkSweepGeneration.cpp 中的collect_in_foreground
我:嗯 嗯 等明年我一定拜读下源码 看源码可能最能理解问题了
我:谢谢啊

复盘如下:

  • 任何形式的垃圾回收,都会造成stop the world,所以其他的线程都会进入暂停状态
  • 如果执行的是FULL GC,就是一次长的stop the world,回收年轻代、老年代、永久代,应该执行的是标记整理算法,彻底的回收资源。
  • Minor GC(年轻代gc),Major GC (老年代gc)
  • CMS GC引入的原因,就是用两次短的stop the world(可能不只两次,重新标记前有可能会主动发起yung gc,导致的暂停我觉得应该算cms引起的),尽量减少工作线程的暂停时间,那么你想啊,作者肯定想方设法的减少暂停时间。所以他内部的细节肯定会很多。