RSet使用 根对象引用的收集算法
ObjA.Filed = ObjB算法
这里指分区里有一个对象存在一个指针指向另外一个分区的对象
须要:数组
老年代分区到新生代分区之间的引用缓存
YoungGC的时候有两种根数据结构
老年代分区到老年代分区之间的引用并发
混合GC的时候可能只有部分分区被回收,必须记录引用关系,快速找到哪些对象是活跃的。
不须要:异步
分区内部的引用关系。性能
对于一个分区来讲,只有回收和不回收,回收的时候就会遍历整个分区,因此无需记录这种引用关系。
新生代分区之间的引用关系:线程
G1的3种回收算法都会处理全部的新生代分区,回收的时候会遍历全部的新生代分区。
新生代分区到老生代分区之间的引用设计
对于YoungGC来讲,针对的新生代,则无需关心;对于混合GC来讲,会使用新生代分区做为根,那么遍历全部新生代分区天然能找到老年代;对于FullGC来讲,全部分区都会被清理,无需关心引用关系。
RSet记录引用者的地址
每一个HR里都包含了一个PRT,它是经过HR中的一个结构 HeapRegionRemSet得到,而每一个HeapRegionRemSet包含了一个OtherRegionsTable,也就PRT。
OtherRegionTable使用了3种粒度来描述引用
Refine线程是G1新引入的并发线程池,线程默认数为 G1ConcTefinementThreads+1
管理RSet。这个是Refine最主要的功能。指针
Refine线程池中的最后一个线程就是抽样线程,主要做用是用来设置新生代分区的个数,使G1知足垃圾回收的停顿预测时间。
G1使用Refine线程 异步维护和管理引用关系。
Refine线程的初始化是在GC管理器初始化的时候进行。JVM经过wait和notify机制实现。
第0个线程何时被激活?
咱们能够设置多个Refine线程工做,在不一样的负载下启用的线程不一样。这个工做负载就经过Refinement Zone控制。
G1提供3个值, Green, Yellow, Red,将整个Queue Set分为4个区。姑且称为白,绿,黄,红
白
绿
黄
红
这3个值经过三个参数处理,默认值都为0,若是不设置,则G1自动推断三个值大小。
ParallelGCThreads = ncpus(cpu内核个数)
假设 ParallelGCThreads = 4 ,G1ConcRefinementThreads =3
这里有4个Refine线程
写屏障是指在改变特定内存的值时(实际上就是写入内存),额外执行的一些动做。
写屏障一般用于在运行时探测并记录回收相关指针,在回收器只回收堆中部分区域的时候,任何来自该区域外的指针都会被写屏障捕获,这些指针将会在垃圾回收的时候做为标记开始的根。
CMS中也是经过写屏障记录引用关系。
每一次将一个老年代对象的引用修改成指向新生代对象,都会被写屏障捕获并记录下来。所以在新生代回收的时候,就能够避免扫描整个老年代来查找根。
不记录新生代到新生代的引用或者新生代到老年代的引用。
过滤后就能使RSet的占用空间大大减小。
垃圾回收的写屏障使用一种两集的缓存结构(用queue set 实现)