1. 程式人生 > >【理解HotSpot虛擬機器】序列垃圾收集器Serial和Serial Old原理

【理解HotSpot虛擬機器】序列垃圾收集器Serial和Serial Old原理

上一篇GC垃圾收集器的對比分析分析和對比了JVM中常見的垃圾收集器,本篇先來探究序列垃圾收集器的原理。

1 Serial 收集器

Serial 收集器是在 DefNewGeneration 新生代上實現收集的,DefNewGeneration上分為3個區:eden 區、 from區和 to 區。Serial 收集器使用複製演算法進行回收複製演算法的思想是將eden和from區活躍的物件複製到to區,並清空eden區和from區,如果to區滿了,那麼部分物件將會被晉升移動到老年代,隨後交換from和to區。

假設我們有如下狀態的 DefNewGeneration 需要收集:



Step 1

遍歷當前記憶體代中所有根物件,eden和from區的根物件將被複制到to區,形成T0物件集



複製eden的根物件

Step 2

遍歷更低記憶體代(DefNewGeneration無更低記憶體代)和更高記憶體代物件(TenuredGeneration)所有物件(實際中無需遍歷所有,而是通過Card Table解決),如果這些物件有引用當前記憶體代的物件,則把物件複製到to區,形成T0物件集



遍歷其他記憶體代的物件

Step 3

通過廣度優先搜尋演算法遍歷掃描活躍物件,即T0物件集



從T0集合開始廣度優先演算法

Step 4

如果Eden區中的物件的age達到_tenuring_threshold,則不是將物件複製到to區,而是提升到高一代(TenuredGeneration)



6號物件的age超過_tenuring_threshold

Step 5

如果to區滿了,eden區中的存活物件也將被提升到高一代(TenuredGeneration)



7號物件因to區滿了也提升到Old區

Step 6

  1. 清除eden區和from區
  2. 交換from區和to區地址

小結

  • 進行GC前需要確定(1)to區為空;(2)下一個記憶體代有足夠的記憶體容納新生代的所有物件
  • Step 1 - Step 3被稱為可達性分析

2 Serial Old 收集器

Serial Old 收集器是在 TenuredGeneration 老年代上實現收集的,Serial Old 收集器 所使用的垃圾回收演算法是標記-壓縮-清理演算法。在回收階段,將標記物件越過堆的空閒區移動到堆的另一端,所有被移動的物件的引用也會被更新指向新的位置。

假設我們有如下狀態的 TenuredGeneration 需要收集:



Step 1 遞迴標記所有活躍物件

與DefNewGeneration類似,以

  • 當前記憶體代中所有根物件
  • 在當前代中,被更低記憶體代(DefNewGeneration)和更高記憶體代物件(TenuredGeneration無更高代)任意物件引用的當前記憶體代的物件

為初始集合,採用廣度優先演算法查詢當前代中的存活物件



Step 2 計算所有活躍物件在壓縮後的偏移地址

遍歷所有的物件,為存活物件重新計算新物件的地址,並將新地址設定為存活物件的轉發指標



Step 3 更新物件的引用地址

遍歷各記憶體代物件/引用,若物件所引用的物件已經被標記,則更新其引用地址為轉發指標所轉向的新地址。



Step 4 移動所有活躍/存活物件到新的位置

遍歷TenuredGeneration物件,對於存活物件,複製原物件的資料內容到壓縮後的地址(即轉發指標的地址),並初始化新的位置的物件的MarkWord



小結

  • 用廣度優先方法作可達性時,DefNewGeneration 是用to區來儲存結果,而 TenuredGeneration 是用一個臨時stack來儲存結果
  • 標記物件:設定物件的物件頭為被標記狀態,有些物件的物件頭可能包含一些資訊,需要在GC結束之後進行恢復,所以標記前需儲存物件和對應的物件頭

3 參考