《垃圾回收的算法與實現》——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)長,兩個階段均要遍歷整個堆。

改進

多個空閒鏈表

針對分配速度慢html

  • 根據塊的大小創建不一樣的空閒鏈表,相同大小的塊連接到相同鏈表中。
  • 因爲對於大塊的申請比較少,所以主要針對小塊創建鏈表,對於大塊的能夠都在同一個鏈表中,如大於2-100的分別創建各自大小的鏈表而大於100的都寫入一個大塊鏈表。

BiBOP

針對碎片化算法

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

位圖標記

針對寫時複製markdown

  • 因爲GC過程須要修改對象中屬性致使寫時複製不兼容,所以指收集各個對象的標誌位並表格化。
  • 將堆中的對象與位圖對應上,然後經過位圖的標誌表明堆中對象的標誌。
  • 優勢:
    • 兼容寫時複製
    • 清除階段能夠快速的去除標記。

延遲清除法

針對STW過長post

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

轉載於:https://www.cnblogs.com/suolu/p/6649211.htmlhtm