Java垃圾回收之標記清除算法詳解
java垃圾回收算法之-引用計數(shù)器,這個算法其中一個優(yōu)點便是,實時性,只要對象的引用計數(shù)器的值為0,則立刻回收。接下來介紹的標記清除算法,當對象的引用計數(shù)器的值為0時,不會立刻被回收的。
概念介紹
root對象
在標記清除算法中,會把如下對象稱之為root對象
- 被棧中的變量(棧中存的是對象的引用)所引用的對象
- 被static變量引用的對象
可訪問的對象
如果棧中有一個變量a引用了一個對象,那么該對象是可訪問的,如果該對象中的某一個字段引用了另一個對象b,那么b也是可訪問的??稍L問的對象也稱之為live
對象
標記清除算法介紹
該算法有兩個階段。
1. 標記階段:找到所有可訪問的對象,做個標記
2. 清除階段:遍歷堆,把未被標記的對象回收
備注:
- 該算法一般應用于老年代,因為老年代的對象生命周期比較長。
標記階段算法
偽代碼類似如下:
for each root variable r mark (r); sweep ();
為了能夠區(qū)分對象是live的,可以為每個對象添加一個marked字段,該字段在對象創(chuàng)建的時候,默認值是false
假設有一個對象p,p對象還間接的引用了其他對象,那么可以使用一個遞歸算法去進行標記,例如:
void mark(Object p) if (!p.marked) p.marked = true; for each Object q referenced by p mark (q);
這個mark方法只有當所有對象已經(jīng)被mark后才會退出。
清除階段算法
在這個階段,需要去遍歷堆中所有對象,并找出未被mark的對象,進行回收。與此同時,那些被mark過的對象的marked字段的值會被重新設置為false,以便下次的垃圾回收。
偽代碼如下:
void sweep () for each Object p in the heap if (p.marked) p.marked = false else heap.release (p);
下面用一張圖來表示標記清除算法的整個過程。
標記清除算法的優(yōu)點和缺點
1. 優(yōu)點
- 是可以解決循環(huán)引用的問題
- 必要時才回收(內(nèi)存不足時)
2. 缺點:
- 回收時,應用需要掛起,也就是stop the world。
- 標記和清除的效率不高,尤其是要掃描的對象比較多的時候
- 會造成內(nèi)存碎片(會導致明明有內(nèi)存空間,但是由于不連續(xù),申請稍微大一些的對象無法做到),如下圖:
解決循環(huán)引用
出現(xiàn)循環(huán)引用的代碼如下:
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對象是沒有被標記的,會被直接回收。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請查看下面相關(guān)鏈接
相關(guān)文章
關(guān)于yml文件字符串,List,Map的書寫方式并使用@ConfigurationProperties注入配置類
這篇文章主要介紹了關(guān)于yml文件字符串,List,Map的書寫方式并使用@ConfigurationProperties注入配置類,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12解決IDEA創(chuàng)建第一個spring boot項目提示cannot resolve xxx等
這篇文章主要介紹了解決IDEA創(chuàng)建第一個spring boot項目提示cannot resolve xxx等錯誤問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01SpringAnimation 實現(xiàn)菜單從頂部彈出從底部消失動畫效果
最近做項目遇到這樣一個需求,要求實現(xiàn)一種菜單,菜單從頂部彈入,然后從底部消失,頂部彈入時,有一個上下抖動的過程,底部消失時,先向上滑動,然后再向下滑動消失。下面給大家?guī)砹藢崿F(xiàn)代碼,感興趣的朋友一起看看吧2018-05-05springboot對接minio的webhook完整步驟記錄
Minio是一款開源的對象存儲服務,它致力于為開發(fā)者提供簡單、高性能、高可用的云存儲解決方案,下面這篇文章主要給大家介紹了關(guān)于springboot對接minio的webhook的相關(guān)資料,需要的朋友可以參考下2024-07-07MyBatis/mybatis-plus項目打印SQL的方法實現(xiàn)
SpringBoot項目中,經(jīng)常需要打印SQL語句及其參數(shù),本文就來介紹一下MyBatis/mybatis-plus項目打印SQL的方法實現(xiàn),具有一定的參考價值,感興趣的可以了解一下2024-07-07Java中String、StringBuffer、StringBuilder的區(qū)別詳解
java中String、StringBuffer、StringBuilder是編程中經(jīng)常使用的字符串類,他們之間有什么區(qū)別呢?下面小編給大家總結(jié)了Java中String、StringBuffer、StringBuilder的區(qū)別詳解,需要的朋友參考下吧2016-06-06