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