《垃圾回收的算法與實現》——GC標記-清除算法
基本算法
- 標記-清除算法由 ==標記階段== 和 ==清除階段== 構成。
- 標記即將全部活動的對象打上標記。
- 清除即將那些沒有標記的對象進行回收。
標記與清除
- 遍歷GC root引用,遞歸標記(設置對象頭中的標誌位)對象。
- 標記時若是標誌位表示已經標記過則能夠跳過。
- 遍歷對象有深度優先與廣度優先兩種算法,其搜索的步驟數一致,而深度優先的內存使用量更小,所以通常使用深度優先。
- 清除階段將再次遍歷堆,未標記的對象加入到空閒鏈表中,標記的對象則去除標記。
分配與合併
- 分配指mutator(Application)申請分塊時獲取內存塊的過程。
- 分配即經過搜索空閒鏈表,找到一個大小合適的塊。分配測量有以下:
- First-fit,找到第一個大於要求大小的塊即返回。
- Best-fit,找到比要求大小大的最小塊。
- Worst-fit,找出最大的塊將其分割成要求大小塊和剩餘的,通常不使用(容易產生碎片)
- 對於內存中連續的垃圾能夠對其進行合併,減小碎片。
優缺點
優勢
- 算法實現簡單。
- 與保守式GC算法兼容(對象不能被移動)。
缺點
- 碎片化。
- 分配速度慢,每次分配須要遍歷空閒鏈表。
- 與寫時複製(copy-on-write)衝突,由於作GC時須要將對象頭進行標記,這將致使大量的數據發生複製。
- STW(Stop-The-World)長,兩個階段均要遍歷整個堆。
改進
多個空閒鏈表
針對分配速度慢算法
- 根據塊的大小創建不一樣的空閒鏈表,相同大小的塊連接到相同鏈表中。
- 因爲對於大塊的申請比較少,所以主要針對小塊創建鏈表,對於大塊的能夠都在同一個鏈表中,如大於2-100的分別創建各自大小的鏈表而大於100的都寫入一個大塊鏈表。
BiBOP
針對碎片化對象
- 原理:將大小相近的對象整理成固定大小的塊進行管理。
- 把堆分割成固定大小的塊,讓每一個塊只能配置一樣大小的對象。
- 可是並不能很好的消除碎片化,若是對堆的分隔沒控制好反而可能致使堆的利用率。
位圖標記
針對寫時複製遞歸
- 因爲GC過程須要修改對象中屬性致使寫時複製不兼容,所以指收集各個對象的標誌位並表格化。
- 將堆中的對象與位圖對應上,然後經過位圖的標誌表明堆中對象的標誌。
- 優勢:
延遲清除法
針對STW過長內存
- 延遲清除法(Lazy-Sweep)是縮減清除操做而致使的mutator STW的方法。
- 標記結束後不作清除操做而是在分配操做中進行。
- 在分配時,從上次遍歷結束的地方開始使用First-fit查找塊,若是找不到返回NULL,此時進行標記階段然後再次進行First-fit查找。還找不到則分配失敗。
歡迎關注本站公眾號,獲取更多信息