JVM中判定對象需要回收的方法
引用計數(shù)法
每個對象上都有一個引用計數(shù),對象每被引用一次,引用計數(shù)器就+1,對象引用被釋放,引用計數(shù)器-1,直到對象的引用計數(shù)為0,對象就標識可以回收
這個可以用數(shù)據(jù)算法中的圖形表示,對象A-對象B-對象C 都有引用,所以不會被回收,對象B由于沒有被引用,沒有路徑可以達到對象B,對象B的引用計數(shù)就就是0,對象B就會被回收。
但是這個算法有明顯的缺陷,對于循環(huán)引用的情況下,循環(huán)引用的對象就不會被回收。例如下圖:對象A,對象B 循環(huán)引用,沒有其他的對象引用A和B,則A和B 都不會被回收。
root搜索算法
這種算法目前定義了幾個root,也就是這幾個對象是jvm虛擬機不會被回收的對象,所以這些對象引用的對象都是在使用中的對象,這些對象未使用的對象就是即將要被回收的對象。簡單就是說:如果對象能夠達到root,就不會被回收,如果對象不能夠達到root,就會被回收。
被啟動類(bootstrap加載器)加載的類和創(chuàng)建的對象
jvm運行時方法區(qū)類靜態(tài)變量(static)引用的對象
jvm運行時方法去常量池引用的對象
jvm當前運行線程中的虛擬機棧變量表引用的對象
本地方法棧中(jni)引用的對象
jvm在確定是否回收的對象的時候采用的是root搜索算法來實現(xiàn)。
補充:jvm判斷對象的回收
可達性分析算法
可達性分析算法:通過一系列“GC Roots”的根對象作為起始節(jié)點集,根據(jù)引用關(guān)系向下搜索,若某個對象到根對象無任何引用鏈相連,則此對象不可達。
但是可達性分析后為不可達的對象不是一定要回收,會經(jīng)歷一個二次標記過程。
二次標記
1.如果對象在可達性分析后結(jié)果為不可達,則會被第一次標記。接著進行篩選,篩選條件為是否執(zhí)行finalize()方法。
- 若該對象未覆蓋finalize()方法,或finalize()已被調(diào)用過一次,則不需要執(zhí)行finalize()方法。那么此對象判定為需要回收。
(對象的 finalize()方法只會被系統(tǒng)調(diào)用一次,下次回收該對象時, finalize()不會再執(zhí)行)
- 若該對象覆蓋了finalize()方法,且finalize()方法未被調(diào)用過,則需要執(zhí)行finalize()方法。
2.若該對象需要執(zhí)行finalize()方法,則該對象會被放置在一個F-Queue的隊列中,再由一個finalizer線程執(zhí)行這些對象的finalize()方法。
3.接著收集器會堆F-Queue隊列的對象進行二次標記,若對象在finalize() 方法中未能逃脫,那么該對象會被二次標記,二次標記的對象判定為需要回收;
(對象可以在 finalize()方法中,將自己和引用鏈上的對象建立引用關(guān)系,這樣在第二次標記時,收集器會將其移出回收對象的集合,以此達到逃脫)
到此這篇關(guān)于jvm中如何判定對象需要回收的文章就介紹到這了,更多相關(guān)jvm判斷對象回收內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決Spring或SpringBoot開啟事務以后無法返回自增主鍵的問題
這篇文章主要介紹了解決Spring或SpringBoot開啟事務以后無法返回自增主鍵的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07SpringBoot JPA實現(xiàn)增刪改查、分頁、排序、事務操作等功能示例
本篇文章主要介紹了SpringBoot JPA實現(xiàn)增刪改查、分頁、排序、事務操作等功能示例,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2017-03-03Java中統(tǒng)計字符個數(shù)以及反序非相同字符的方法詳解
本篇文章是對Java中統(tǒng)計字符個數(shù)以及反序非相同字符的方法進行了詳細的分析介紹,需要的朋友參考下2013-05-05