在方法执行的过程中, 可能会导致引用关系发生变化,那么保存的OopMap就要随着变化。如果每次引用关系发生了变化都要去修改OopMap的话,这又是一件成本很高的事情。所以这里就引入了安全点的概念。
OopMap的作用是为了在GC的时候,快速进行可达性分析,所以OopMap并不需要一发生改变就去更新这个映射表。只要这个更新在GC发生之前就可以了。所以OopMap只需要在预先选定的一些位置上记录变化的OopMap就行了。这些特定的点就是SafePoint(安全点)。由此也可以知道,程序并不是在所有的位置上都可以进行GC的,只有在达到这样的安全点才能暂停下来进行GC。
在垃圾收集发生时让所有线程跑到最近的安全点的方法:
抢断式中断
抢断式中断就是在GC的时候,让所有的线程都中断,如果这些线程中发现中断地方不在安全点上的,就恢复线程,让他们重新跑起来,直到跑到安全点上。
主动式中断
主动式中断在GC的时候,不会主动去中断线程,仅仅是设置一个标志,当程序运行到安全点时就去轮训该位置,发现该位置被设置为真时就自己中断挂起。所以轮训标志的地方是和安全点重合的,另外创建对象需要分配内存的地方也需要轮询该位置。
1、循环的末尾
2、方法临返回前
3、调用方法之后
4、抛异常的位置
安全区域有些线程执行到某些代码之后就不再执行,而是挂起,这时候对象之间的引用关系不会发生改变,在这时候进行垃圾收集是安全的。这类区域就叫做安全区域。
安全区域可以是安全点的一个扩展。
当线程处于安全区域内之后,将自己标记为处于安全区之中。当线程在安全区域当中需要离开的时候,需要判断是否在进行根节点的枚举,如果是处于根节点枚举过程序,则等待垃圾收集器给出信号才可以离开。
记忆集在进行垃圾收集的时候,可能存在跨代引用。如老年代引用新生代对象。这时候,为了避免直接扫描整个老年代对象区域,可以建立一个数据结构,用于记录其他区域指向当前区域的引用,从而避免了扫描全部区域。 卡表是记忆集的一种实现方式.
写屏障当有其他区域对象指向当前区域对象的时候,需要有一个方法将对象卡表变脏。具体实现方式是在虚拟机层面进行对象引用赋值操作的时候,形成类似于AOP切面可以在赋值前后进行相应操作。赋值前叫做写前屏障,赋值后叫写后屏障。
并发的可达性分析基本上所有垃圾收集器的垃圾回收都会有标记这一步(标记对象是否是可以到达的)。由于对象区域很大,在这个区域可以与用户线程并行执行,将会是很高效的。
在三色原理过程中得出结论,对象消失仅有以下两种情况:
赋值器插入了一条或者多条从黑色对象指向白色对象的引用。
赋值器删除了全部从灰色对象指向白色对象的引用。
如果能破坏两个条件中的一个,就可以解决并发扫描对象消失的问题。带来的方案也对应的有以下两种:
增量更新增量更新要破坏的是第一个条件(赋值器插入了一条或者多条从黑色对象到白色对象的新引用),当黑色对象插入新的指向白色对象的引用关系时,就将这个新插入的引用记录下来,等并发扫描结束之后,再将这些记录过的引用关系中的黑色对象为根,重新扫描一次。
可以简化的理解为:黑色对象一旦插入了指向白色对象的引用之后,它就变回了灰色对象。
原始快照原始快照要破坏的是第二个条件(赋值器删除了全部从灰色对象到该白色对象的直接或间接引用),当灰色对象要删除指向白色对象的引用关系时,就将这个要删除的引用记录下来,在并发扫描结束之后,再将这些记录过的引用关系中的灰色对象为根,重新扫描一次。
这个可以简化理解为:无论引用关系删除与否,都会按照刚刚开始扫描那一刻的对象图快照开进行搜索。
经典垃圾收集器 Serial收集器Serial收集器是最基础、历史最悠久的收集器。是一个单线程工作的收集器。在它进行垃圾收集时必须暂停其他所有工作线程。
ParNew收集器ParNew收集器实质上是Serial收集器的多线程并行版本,除了同时使用多条线程进行垃圾收集之外,其余的行为和Serial收集器基本一致
目前只有它能够与CMS收集器配合工作
Parallel Scanvenge收集器Parallel Scanvenge是新生代收集器,使用标记-复制,并行收集,与ParNew非常相似。特点是CMS等收集器关注的尽可能缩短垃圾收集时用户线程的停顿时间。而Parallel Scanvenge收集器的目标是达到一个可控制的吞吐量。吞吐量就是运行用户代码和处理器总耗时时间。停顿时间越短越适合与用户交互或者需要保证服务响应质量的程序,高吞吐量则可以最高效率地用处理资源,尽快完成程序的任务。经常被称作“吞吐量优先收集器“
Serial Old收集器Serial Old是Serial收集器的老年代版本,同样是单线程收集器,使用标记-整理算法。
Parallel Old收集器Parallel Old是Parallel Scavenge收集器的老年代版本,支持多线程并行收集,基于标记-整理算法实现.
CMS收集器CMS收集器是一种以获取最短回收停顿时间为目标的收集器。基于标记-清除算法。
运作过程分为四个步骤:初始标记,并发标记,重新标记,并发清除
由于CMS收集器无法处理“浮动垃圾”有可能出现"Con-current Mode Failure"失败进而导致另一次完全“Stop The World”的Full GC的产生
Garbage First 收集器Garbage First收集器是垃圾搜集器技术发展历史上的里程碑式的成果,开创了收集器面向局部收集的设计思路和基于Region的内存布局形式