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 實現)