标記-清除算法
标記-清除算法(mark-sweep
1 标記-清除算法 回收過程描述
類别
描述
mutator
設定
collector
收集
mutator roots
mutator根對象
1 在應用程式中 mutator是指除了垃圾收集器之外的部分,比如說我們應用程式本身。mutator的職責一般是NEW(配置設定記憶體),READ(從記憶體中讀取内容),WRITE(将内容寫入記憶體)
2 collector指的就是垃圾收集器 collector則就是回收不再使用的記憶體來供mutator進行NEW操作的使用
3 mutator根對象一般指的是配置設定在堆記憶體之外,可以直接被mutator直接通路到的對象,一般是指靜态/全局變量以及Thread-Local變量(在Java中,存儲在java.lang.ThreadLocal中的變量和配置設定在棧上的變量 - 方法内部的臨時變量等都屬于此類).
标記-清除算法分為兩個階段,标記(mark)和清除(sweep).
在标記階段,collector(垃圾收集器)從mutator根對象開始進行周遊,對從mutator根對象可以通路到的對象都打上一個辨別,一般是在對象的header中,将其記錄為可達對象
在清除階段,collector(垃圾收集器)對堆記憶體(heap memory)從頭到尾進行線性的周遊,如果發現某個對象沒有标記為可達對象-通過讀取對象的header資訊,則就将其回收。collector(垃圾收集器)在進行标記和清除階段時會将整個應用程式暫停(mutator),等待标記清除結束後才會恢複應用程式的運作,這也是Stop-The-World這個單詞的來曆
2 标記-清除算法 從C語言的角度來看
New():
//allocate() C語言中的記憶體動态配置設定
//配置設定新的記憶體到ref指針
ref
//如果配置設定的記憶體為 null
//也就是記憶體不足,則觸發垃圾收集
if ref == null
collect()
//垃圾收集後 再配置設定新的記憶體
//仍然記憶體不足,
//則抛出Out of Memory錯誤
ref
if ref == null
throw "Out of Memory"
return ref
atomic collect():
//mark标記
markFromRoots()
sweep(HeapStart,HeapEnd)
markFromRoots():
worklist
for each fld in Roots //周遊所有mutator根對象
ref
if ref != null && isNotMarked(ref) //如果它是可達的而且沒有被标記的,直接标記該對象并将其加到worklist中
setMarked(ref)
add(worklist,ref)
mark()
mark():
while not isEmpty(worklist)
ref
for each fld in Pointers(ref) //周遊ref對象的所有指針域,如果其指針域(child)是可達的,直接标記其為可達對象并且将其加入worklist中
//通過這樣的方式來實作深度周遊,直到将該對象下面所有可以通路到的對象都标記為可達對象。
child
if child != null && isNotMarked(child)
setMarked(child)
add(worklist,child)
mark标記完成後,sweep清除階段 就是從堆記憶體起始位置開始,線性周遊所有對象直到堆記憶體末尾,如果該對象是可達對象的(在mark階段被标記過的),那就直接去除标記位(為下一次的mark做準備),如果該對象是不可達的,直接釋放記憶體。
sweep(start,end):
scan
while scan < end
if isMarked(scan)
setUnMarked(scan)
else
free(scan)
scan
本文同步分享在 部落格“早起的年輕人”(CSDN)。
如有侵權,請聯系 [email protected] 删除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。