企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
### G1:remember set 理解RSet首先需要知晓如下几点: * 一个对象会被不同region的其他对象引用,这些region可能属于不同的代,判断对象是否存活的时候,不能能只考虑属于一个代中的region内对象。 * 其他分代垃圾收集器也存在该问题,G1由于分区算法的原因,这个问题更为突出 * 比如回收新生代的时候也不得不扫描老年代? * 比如可达性分析算法的GC Roots集合可能在不同的代中,所以从所有GC Roots出发扫描关联引用的对象的时候是会涉及所有代的。 * 如果为了回收某个代中的垃圾对象而扫描整个堆,这样必然会降低垃圾回收的效率 * **所以堆内会有一部分的内存用来储存对象引用关系,也就是堆内存并不能完全用来存放对象数据** 解决方法就是**使用remember set来避免全局扫描**: ![](https://img.kancloud.cn/82/16/8216aabbe902e70ec07c4876f7a55217_1198x445.png) 上图中region2的RSet记录了两个引用到本region内对象的关系 * 每个region都有自身对应的一个记忆集RSet * 每次引用类型数据写操作的时候,都会产生一个写屏障(Write Barrier)暂时的中断操作 * 然后检查将要写入的引用指向的对象是否和该引用类型数据在不同的region(其他收集器将会检查老年代对象是否引用了新生代对象) * 如果不同,通过CardTable把相关引用信息记录到引用指向对象所在的region对象的RSet中 * 当进行垃圾收集时,在GC根节点的枚举范围内加入RSet,就可以保证不进行全局的对象关系扫描。