Java垃圾回收之標記清除算法詳解

Java垃圾回收之標記清除算法詳解

java垃圾回收算法之-引用計數器,這個算法其中一個優勢即是,實時性,只要對象的引用計數器的值爲0,則馬上回收。接下來介紹的標記清除算法,當對象的引用計數器的值爲0時,不會馬上被回收的。html

概念介紹java

root對象算法

在標記清除算法中,會把以下對象稱之爲root對象jvm

  1. 被棧中的變量(棧中存的是對象的引用)所引用的對象ide

  2. 被static變量引用的對象學習

可訪問的對象spa

若是棧中有一個變量a引用了一個對象,那麼該對象是可訪問的,若是該對象中的某一個字段引用了另外一個對象b,那麼b也是可訪問的。可訪問的對象也稱之爲orm

live

對象htm


標記清除算法介紹對象

該算法有兩個階段。 

1. 標記階段:找到全部可訪問的對象,作個標記 
2. 清除階段:遍歷堆,把未被標記的對象回收

備註:

  • 該算法通常應用於老年代,由於老年代的對象生命週期比較長。

標記階段算法

僞代碼相似以下:

for each root variable r
mark (r);
sweep ();

爲了可以區分對象是live的,能夠爲每一個對象添加一個marked字段,該字段在對象建立的時候,默認值是false 

假設有一個對象p,p對象還間接的引用了其餘對象,那麼可使用一個遞歸算法去進行標記,例如:

void mark(Object p)
if (!p.marked)
p.marked = true;
for each Object q referenced by p
mark (q);

這個mark方法只有當全部對象已經被mark後纔會退出。

清除階段算法

在這個階段,須要去遍歷堆中全部對象,並找出未被mark的對象,進行回收。與此同時,那些被mark過的對象的marked字段的值會被從新設置爲false,以便下次的垃圾回收。 

僞代碼以下:

void sweep ()
for each Object p in the heap
if (p.marked)
p.marked = false
else
heap.release (p);

下面用一張圖來表示標記清除算法的整個過程。

標記清除算法的優勢和缺點

1. 優勢 
- 是能夠解決循環引用的問題 
- 必要時纔回收(內存不足時)

2. 缺點: 
- 回收時,應用須要掛起,也就是stop the world。 
- 標記和清除的效率不高,尤爲是要掃描的對象比較多的時候 
- 會形成內存碎片(會致使明明有內存空間,可是因爲不連續,申請稍微大一些的對象沒法作到),以下圖:

解決循環引用

出現循環引用的代碼以下:

class TestA{
public TestB b;
}
class TestB{
public TestA a;
}
public class Main{
public static void main(String[] args){
A a = new A();
B b = new B();
a.b=b;
b.a=a;
a = null;
b = null;
}
}

對應的圖以下:

這個時候,當a = null; b = null;的時候,圖像變成以下:

那麼使用標記清除算法是能夠回收a和b的,緣由是標記清除算法是從棧中根對象開始的,改算法走完後,a對象和b對象是沒有被標記的,會被直接回收。

總結

以上就是這篇文章的所有內容了,但願本文的內容對你們的學習或者工做具備必定的參考學習價值,謝謝你們對腳本之家的支持。若是你想了解更多相關內容請查看下面相關連接

您可能感興趣的文章:

文章同步發佈: https://www.geek-share.com/detail/2751539805.html

相關文章
相關標籤/搜索