其他? 为什么不把初始标记和并发标记放在一起?
1.初始标记是需要STW的,而并发标记是不需要STW的。2.并且初始标记是需要找到GC Root供第二步的并发标记用的
为什么初始标记需要STW,而并发标记不需要STW呢,为什么重新标记STW?
那是因为GC Root是变动的,比如栈帧中的本地变量表作为GC Root可能时刻在变化,所以必须先STW然后再扫描整个GC Root
在并发标记的期间会出现漏标和多标的对象,所以为了修正这部分对象,需要在重新标记期间STW
9.STW什么时候触发?
虚拟机采用主动式中断方案,各个线程主动轮询标志位,一旦发现中断标志, 就在最近的安全点上主动中断挂起。
9.什么是STW?
在垃圾回收算法执行当中,需要将这JVM内存冻结的一种状态。Java的所有的线程都会停止,但是GC线程除外,本地方法也可以执行,但是不能和JVM交互。GC各种算法优化的重点就是减少STW,这也是JVM调优的重点。
9.什么是STW?什么是安全点?什么是安全区域?
安全点:
1.用户线程暂停,gc线程要开始工作,但是要确保用户线程暂停的这行字节码指令是不会引起引用关系的变化
2.所以JVM会在字节码指令中选一些指令作为安全点,如方法调用,循环跳转等
3.GC是主动式中断,主动式中断是设置一个标志,这个标志是中断标志,各个业务线程,在运行过程中会不停地主动去轮询这个标志,一旦发现是true,就会在自己最近的安全点上主动中断挂起
安全区域:
能够在某一段代码片段之中,引用关系不会发生变化,因此,在这个区域中,任意地方开始垃圾收集都是安全的,相当于被扩展拉伸了的安全点
9.为什么需要安全区域?
要是业务线程都不执行,比如业务线程,处于sleep或者是阻塞状态.那么程序就没办法进入安全点,至于这种情况就必须引入安全区域
CMS和G1区别
作用范围
CMS针对老年代。可以配合Serial 或 Parallel New这些新生代的垃圾回收器。如果碎片过多,老年代会使用Serial Old进行垃圾回收
G1则是针对 老年代和新生代
停顿时间
CMS以最小停顿时间为目标
G1可以预测垃圾回收时间
垃圾碎片
CMS收集器使用标记-清除算法进行垃圾回收,容易产生碎片
G1由于使用了Region的概念,降低了内存碎片
大对象处理
除了上面优点之外,还有一个优点,那就是对大对象的处理。在CMS内存中,如果一个对象过大,进入S1、S2区域的时候大于改分配的区域,对象会直接进入老年代。G1处理大对象时会判断对象是否大于一个Region大小的50%,如果大于50%就会横跨多个Region进行存放
10.CMS G1垃圾回收器的三色标记了解过吗?
三色标记法是一种垃圾回收法,它可以让JVM不发生或短时间发生STW,从而达到清除内存垃圾的目的
将对象的颜色分为黑,灰,白三种颜色
黑色:该对象及其下一个属性全部被标记过
灰色:对象已被垃圾收集器扫描过了,但是对象中还有未扫描的引用
白色:没有被垃圾扫描收集器访问过,既表示不可达
存在问题:漏标问题不是垃圾的,当做垃圾
A为黑,b为灰,c为白
如a新增引用c
删掉了b到c的引用,导致c为不可达,但是a引用了c
CMS解决:重新扫描,增量更新
当未被标记的对象被重新引用后,引用它的对象如果是黑色的话,那么会将颜色置为灰色,在二次标记的时候让GC线程继续标记它的属性对象
g1:把删除的引用放到jc的堆栈,找到其是否又被其他对象引用,SATB
在标记开始的时候成成一个快照图标记存活对象
在一个引用断开后,要将此引用推到GC的堆栈中,保证对象还能被GC线程扫描到(通过在 wirte barrier 里把所有旧的引用所指向的对象都变成非白的)
配合Rset(一个空间换时间的工具),去扫描哪些Region引用到当前的白色对象,若没有引用到当前对象,则回收
SATB效率高于增量更新的原因
因为SATB在重新标记环节只需要去重新扫描那些被推到堆栈中的引用,并配合Rset来判断当前对象是否被引用来进行回收;并且在最后G1并不会选择回收所有垃圾对象,而是根据Region的垃圾多少来判断与预估回收价值(指回收的垃圾与回收的STW时间的一个预估值),将一个或者多个Region放到CSet中,最后将这些Region中的存活对象压缩并复制到新的Region中,清空原来的Region。