天天看點

java 标記清除算法_《對Java的分析總結》-Java中的垃圾回收機制中的标記-清除算法 (五)...

标記-清除算法

标記-清除算法(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源創計劃”,歡迎正在閱讀的你也加入,一起分享。