JVM三色标记算法思想
三色标记法是一种垃圾回收法,它可以让JVM不发生或仅短时间发生STW(Stop The World),从而达到清除JVM内存垃圾的目的。
JVM中的CMS、G1垃圾回收器所使用垃圾回收算法即为三色标记法。
之前提到的CMS、G1垃圾回收器所使用垃圾回收算法,分为四个步骤,这四个步骤各不相同,其中标志垃圾的状态和JVM判断垃圾是否需要回收的算法——可达性分析法也有关系。
# 1、可达性分析法
这个算法的基本思路就是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain)。
当一个对象到GC Roots没有任何引用链相连时(不可达)则证明此对象是不可用的。
# 2、三色标记算法思想
三色标记法将对象的颜色分为了黑、灰、白,三种颜色。
白色:该对象没有被标记过。(对象垃圾)
灰色:该对象已经被标记过了,但该对象下的属性没有全被标记完。(GC需要从此对象中去寻找垃圾)
黑色:该对象已经被标记过了,且该对象下的属性也全部都被标记过了。(程序所需要的对象)
# 算法流程
1、从我们main
方法的根对象(JVM中称为GC Root
)开始沿着他们的对象向下查找,用黑灰白的规则,标记出所有跟GC Root
相连接的对象(不递归),扫描一遍结束后,一般需要进行一次短暂的STW(Stop The World)
2、只需找出灰色对象并顺着继续往下标记(且因为大部分的标记工作已经在第一次并发的时候发生了,所以灰色对象数量会很少,标记时间也会短很多), 此时程序继续执行,GC
线程扫描所有的内存,找出扫描之后依旧被标记为白色的对象(垃圾),清除。
具体流程:
- 首先创建三个集合:白、灰、黑。
- 将所有对象放入白色集合中。
- 然后从根节点开始遍历所有对象(注意这里并不递归遍历),把遍历到的对象从白色集合放入灰色集合。
- 之后遍历灰色集合,将灰色对象引用的对象从白色集合放入灰色集合,之后将此灰色对象放入黑色集合
- 重复 4 直到灰色中无任何对象
- 通过write-barrier检测对象有变化,重复以上操作
- 收集所有白色对象(垃圾)
看到这里,这不就是CMS、G1垃圾回收器所使用垃圾回收算法吗?
所以也就恍然大悟了。
CMS、G1的垃圾回收算法和可达性分析法
也有很大关系,所以才会出现这种分批次标志的回收过程。
# 3、G1会不会full gc?
肯定会。
虽然说 G1 回收器相比其他回收器要好,但G1也有缺点,而且在 初始标记 、 最终标记 还是会发生full gc
且JDK10
之前的Full GC
,为单线程的,所以使用G1需要避免Full GC
的产生。
解决方案:
- 加大内存;
- 提高CPU性能,加快GC回收速度,而对象增加速度赶不上回收速度,则Full GC可以避免;
- 降低进行Mixed GC触发的阈值,让Mixed GC提早发生(默认45%)J
参考:
- https://mp.weixin.qq.com/s/flYwD0e9fXBU_wGT7Wg8eA