GCRoot节点的枚举
由于Java对象太多,在进行根节点枚举的时候,需要遍历找到所有对象显然不太现实(GCRoot的枚举在收集器算法当中一般都需要Stop The World)。
那如何有高效的方法呢?
由于目前主流虚拟机都是采用准确式垃圾收集。在HopSpot解决方案当中,采用的是成为OopMap的数据结构,避免扫描所有对象。 JVM可以做到在类加载完成后,就能获取对象的数据信息。将这些信息放到OopMap中,避免了扫描整个程序上下文。
安全点
在方法执行的过程中, 可能会导致引用关系发生变化,那么保存的OopMap就要随着变化。如果每次引用关系发生了变化都要去修改OopMap的话,这又是一件成本很高的事情。所以这里就引入了安全点的概念。
OopMap的作用是为了在GC的时候,快速进行可达性分析,所以OopMap并不需要一发生改变就去更新这个映射表。只要这个更新在GC发生之前就可以了。所以OopMap只需要在预先选定的一些位置上记录变化的OopMap就行了。这些特定的点就是SafePoint(安全点)。由此也可以知道,程序并不是在所有的位置上都可以进行GC的,只有在达到这样的安全点才能暂停下来进行GC。
那哪些地方可以成为安全点?
以程序长时间执行的特征作为标准选定。需要避免让收集器等待时间过长,同时避免Oopmap更新太频繁。长时间执行的最明显的特征就是指令复用。所以,一般作为安全点的地方有:方法调用,循环跳转,异常跳转
怎么样在发生垃圾收集的时候让所有线程都跑到最近的安全点
抢断式中断
抢断式中断就是在GC的时候,让所有的线程都中断,如果这些线程中发现中断地方不在安全点上的,就恢复线程,让他们重新跑起来,直到跑到安全点上。
主动式中断
主动式中断在GC的时候,不会主动去中断线程,仅仅是设置一个标志,当程序运行到安全点时就去轮训该位置,发现该位置被设置为真时就自己中断挂起。所以轮训标志的地方是和安全点重合的,另外创建对象需要分配内存的地方也需要轮询该位置。
安全区域
有些线程执行到某些代码之后就不再执行,而是挂起,这时候对象之间的引用关系不会发生改变,在这时候进行垃圾收集是安全的。这类区域就叫做安全区域。
安全区域可以是安全点的一个扩展。
当线程处于安全区域内之后,将自己标记为处于安全区之中。当线程在安全区域当中需要离开的时候,需要判断是否在进行根节点的枚举,如果是处于根节点枚举过程序,则等待垃圾收集器给出信号才可以离开。
记忆集
在进行垃圾收集的时候,可能存在跨代引用。如老年代引用新生代对象。这时候,为了避免直接扫描整个老年代对象区域,可以建立一个数据结构,用于记录其他区域指向当前区域的引用,从而避免了扫描全部区域。 卡表是记忆集的一种实现方式.
写屏障
写屏障的出现,解决了对象卡表(记忆集的一种实现)何时变脏,如何将它们变脏的问题。
当有其他区域对象指向当前区域对象的时候,需要有一个方法将对象卡表变脏。具体实现方式是在虚拟机层面进行对象引用赋值操作的时候,形成类似于AOP切面可以在赋值前后进行相应操作。赋值前叫做写前屏障,赋值后叫写后屏障。
并发的可达性分析算法
基本上所有垃圾收集器的垃圾回收都会有标记这一步(标记对象是否是可以到达的)。由于对象区域很大,在这个区域可以与用户线程并行执行,将会是很高效的。
并发可达性分析算法的理论基础是三色原理(太多此处不做描述),但是会存在对象消失的问题。
在三色原理过程中得出结论,对象消失仅有以下两种情况:
赋值器插入了一条或者多条从黑色对象指向白色对象的引用。
赋值器删除了全部从灰色对象指向白色对象的引用。
如果能破坏两个条件中的一个,就可以解决并发扫描对象消失的问题。带来的方案也对应的有以下两种:
增量更新
增量更新要破坏的是第一个条件(赋值器插入了一条或者多条从黑色对象到白色对象的新引用),当黑色对象插入新的指向白色对象的引用关系时,就将这个新插入的引用记录下来,等并发扫描结束之后,再将这些记录过的引用关系中的黑色对象为根,重新扫描一次。
可以简化的理解为:黑色对象一旦插入了指向白色对象的引用之后,它就变回了灰色对象。
原始快照
原始快照要破坏的是第二个条件(赋值器删除了全部从灰色对象到该白色对象的直接或间接引用),当灰色对象要删除指向白色对象的引用关系时,就将这个要删除的引用记录下来,在并发扫描结束之后,再将这些记录过的引用关系中的灰色对象为根,重新扫描一次。
这个可以简化理解为:无论引用关系删除与否,都会按照刚刚开始扫描那一刻的对象图快照开进行搜索。
上面的介绍中无论是对引用关系记录的插入还是删除,虚拟机的记录操作都是通过写屏障实现的。
增量更新用的是写后屏障(Post-Write Barrier),记录了所有新增的引用关系。代表有CMS收集器
原始快照用的是写前屏障(Pre-Write Barrier),将所有即将被删除的引用关系的旧引用记录下来。代表有G1收集器