GC算法-复制算法
概述
復制算法就是將內存空間二等分, 每次只使用其中一塊. 當執行GC時, 講A部分的所有活動對象集體移到B中, 就可以講A全部釋放.
畫個圖就是:
? 在執行GC前, 內存長這樣:
? 當執行GC后, 內存就變成這樣了:
還記得標記清除算法的問題是什么嗎? 內存碎片化嚴重. 現在好了, 碎片化問題解決了, 每次GC執行后, 內存空間都是連續的啦.
實現
想一想GC執行的步驟是什么? 很簡單啊, 遍歷所有可訪問的對象, 將所有對象的復制到另一塊內存中. 完畢.
遍歷所有根集合的對象, 跳過. 將每個對象都調用一次copy函數, 那么, 這個copy函數如何實現呢?
function copy(obj){// 若對象已經被復制過了, 則將其直接返回if(obj.isCopy == true){// 在原來對象中保存一下新的地址, 方便返回return obj.newAddr; }// 這里假設有一個全局變量 ADDR 指向空閑內存的首地址// 這里直接將 obj的size大小復制到ADDR的地方copy_data(ADDR, obj, obj.size);// 記錄復制obj.isCopy = true;obj.newAddr = ADDR;// 更新空閑地址ADDR += size;// 將所有子對象復制for(child in children){child = copy(child);}return obj.newAddr; }將所有根集合中的對象依次調用copy函數, 完成復制.
復制算法分配新的對象變簡單了, 有沒有? 因為地址都是連續的, 所以申請新的地址也不用遍歷鏈表等一堆操作, 直接按著地址劃分空間就行了.
分析
很明顯, 復制算法解決了標記清除的一個大問題, 內存碎片化嚴重. 在這里, 根本不存在碎片化問題的好嘛. 其相比標記清除的優勢還是有一些的:
當然, 缺點也很明顯. 將堆一分為二, 使用效率急速下滑.
我看到有一種多空間復制算法, 為了提高堆的使用效率. 將堆空間分成N份, 其中的兩份使用復制算法, 剩余的使用其他方法執行GC. 我實在是沒有明白這么做的好處在哪…
總結
- 上一篇: 计算机考试演示文稿模板,2018职称计算
- 下一篇: minio部署