并发标记算法
CardTable
由于做YGC时 可能会出现Old区的引用指向y区,那么需要扫描整个old区,效率非常低
所以JVM设计CardTable,将y区和o区分成一个一个card(区分是否有引用指向y区),如果一个o区cardTable中有对象指向y区,那么就将它设为Dirty,下次扫描时,只需要扫描dirtyCard
cardTable 只有一个是card的集合 里面是01的位图 0代表没有对象指向y区 1 代表有对象指向y区
Cset(collectionSet) 那些需要被回收的分区的集合(也就是card为1时有引用指向y区的集合) 分区可以来自伊甸 s区 或者o区
Rset(RememberedSet)
region 里面都有一块区域(hashSet)记录了其他region中的对象到本region的引用,
使得垃圾回收不需要扫描整个堆栈找到谁引用了当前分区中的对象,只需要扫描Rset即可
假如我要回收这块region 那么不需要扫描整个堆栈 因为这个region中有Rset,记录着所有引用了我当前回收的region的对象,如果没有 ,那么直接回收
YGC何时触发?
伊甸区空间不足
多线程并行执行
FGC何时触发?
old区空间不足
System.gc()
G1是否会产生FGC?如果G1产生FGC 应该如何做?
会 当对象分配不下了就会产生FGC
解决方法:
1扩内存
2提高CPU性能
3降低MixedGC的触发阈值 让MixedGC尽早发生(默认值45%)

CMS和G1都是用的三色标记算法 把对象在逻辑上分成三种颜色 1 黑色 自身和成员变量均以标记完成 2 灰色 自身被标记 但是成员变量为被标记 3 白色 未被标记的对象
在并发标记过程(remark 阶段)中 什么情况下容易发生漏标?以下两种情况必须同时发生 就会出现漏标的情况
1 在并发标记过程中 有一个黑色对象引用指向白色对象
2 灰色对象不在指向白色对象
此时这个D是正常对象 但是漏标无法找到 当成垃圾回收了
解决并发标记产生漏标问题
1 increment update 增量更新 关注引用的增加 把黑色重新标记为灰色 下次重新扫描属性 CMS算法实现
2 SATB snapshot at the beginning 关注引用的删除 当B->D 消失时,要把这个引用推到GC的堆栈,保证D还能被GC扫描到 G1算法实现
2.1 GC里面会有一个栈 这个栈中装着灰色对象指向白色对象的引用 如果B->D引用消失掉 还是可以在栈中找到 重新扫描栈中的引用即可
为什么G1使用SATB?
1 increment update 之前已经标记过得 还是要重新扫描 当这个黑色标记的引用很多,那么效率较低
SATB 将那些之前改变过的 那些堆栈中的引用 直接扫描一遍
2 为了配合Rset
如果灰色 到 白色消失,如果黑色 没有指向 白色,引用会被push到堆栈,
下次扫描时拿到这个引用,由于Rset的存在,不需要扫描整个堆去查找指向白色的引用,效率较高

浙公网安备 33010602011771号