《垃圾回收的算法與實現》——GC標記-清除算法


基本算法

  • 標記-清除算法由 標記階段清除階段 構成。
  • 標記即將所有活動的對象打上標記。
  • 清除即將那些沒有標記的對象進行回收。

標記與清除

  • 遍歷GC root引用,遞歸標記(設置對象頭中的標志位)對象。
  • 標記時如果標志位表示已經標記過則可以跳過。
  • 遍歷對象有深度優先與廣度優先兩種算法,其搜索的步驟數一致,而深度優先的內存使用量更小,因此一般使用深度優先。
  • 清除階段將再次遍歷堆,未標記的對象加入到空閑鏈表中,標記的對象則去除標記。

分配與合並

  • 分配指mutator(Application)申請分塊時獲取內存塊的過程。
  • 分配即通過搜索空閑鏈表,找到一個大小合適的塊。分配測量有如下:
    • First-fit,找到第一個大於要求大小的塊即返回。
    • Best-fit,找到比要求大小大的最小塊。
    • Worst-fit,找出最大的塊將其分割成要求大小塊和剩余的,一般不使用(容易產生碎片)
  • 對於內存中連續的垃圾可以對其進行合並,減少碎片。

優缺點

優點

  1. 算法實現簡單。
  2. 與保守式GC算法兼容(對象不能被移動)。

缺點

  1. 碎片化。
  2. 分配速度慢,每次分配需要遍歷空閑鏈表。
  3. 與寫時復制(copy-on-write)沖突,因為做GC時需要將對象頭進行標記,這將導致大量的數據發生復制。
  4. STW(Stop-The-World)長,兩個階段均要遍歷整個堆。

改進

多個空閑鏈表

針對分配速度慢

  • 根據塊的大小建立不同的空閑鏈表,相同大小的塊鏈接到相同鏈表中。
  • 由於對於大塊的申請比較少,因此主要針對小塊建立鏈表,對於大塊的可以都在同一個鏈表中,如大於2-100的分別建立各自大小的鏈表而大於100的都寫入一個大塊鏈表。

BiBOP

針對碎片化

  • 原理:將大小相近的對象整理成固定大小的塊進行管理。
  • 把堆分割成固定大小的塊,讓每個塊只能配置同樣大小的對象。
  • 但是並不能很好的消除碎片化,如果對堆的分隔沒控制好反而可能導致堆的利用率。

位圖標記

針對寫時復制

  • 由於GC過程需要修改對象中屬性導致寫時復制不兼容,因此指收集各個對象的標志位並表格化。
  • 將堆中的對象與位圖對應上,而后通過位圖的標志代表堆中對象的標志。
  • 優點:
    • 兼容寫時復制
    • 清除階段可以快速的去除標記。

延遲清除法

針對STW過長

  • 延遲清除法(Lazy-Sweep)是縮減清除操作而導致的mutator STW的方法。
  • 標記結束后不做清除操作而是在分配操作中進行。
  • 在分配時,從上次遍歷結束的地方開始使用First-fit查找塊,如果找不到返回NULL,此時進行標記階段而后再次進行First-fit查找。還找不到則分配失敗。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM