java判断对象已死_Java的JVM判断对象已死的基本算法分析
jvm中有各種的垃圾收集器,每個(gè)收集器都有各自的算法。但是一切的根本都需要找到找到應(yīng)該被消除的對(duì)象,理解如何找到死亡對(duì)象才是理解垃圾收集器的基礎(chǔ)。
01兩個(gè)基本算法
a、引用記數(shù)法:對(duì)象中加一個(gè)引用計(jì)數(shù)器,每次被引用計(jì)數(shù)器加一,引用失效減一,當(dāng)減到0的時(shí)候就不會(huì)在被再引用了,就可以回收了。
優(yōu)點(diǎn):原理簡(jiǎn)單,效率高。
缺點(diǎn):有很多例外情況要用大量額外的處理,比如兩個(gè)對(duì)象相互引用。
b、可達(dá)性分析:通過(guò)一系列“GC Roots”的根對(duì)象為起始,根據(jù)引用關(guān)系向下搜索,搜索路徑形成引用鏈,而那些沒(méi)有在任何引用鏈上的叫做不可達(dá)對(duì)象,都是不可能被再次使用的。如下圖,紅色部分就是需要回收的。
兩種算法對(duì)比如下:
02GC Roots包含哪些
可達(dá)性分析首先要確認(rèn)的是GC Roots,只有選擇合適的GC Roots才能真正的找到應(yīng)該存在的對(duì)象和排除不應(yīng)該存在的對(duì)象。GC Roots主要包含以下:
a、虛擬機(jī)棧中的對(duì)象,就是各個(gè)線程的方法里面的方法參數(shù)、局部變量、臨時(shí)變量。
b、方法區(qū)中類的靜態(tài)屬性引用的對(duì)象。
c、方法區(qū)中常量引用的對(duì)象,比如字符串常量池的引用。
d、本地方法棧引用的對(duì)。
e、虛擬機(jī)內(nèi)部的引用,基本類型對(duì)應(yīng)的class對(duì)象,常駐異常對(duì)象,系統(tǒng)類加載器。
f、所有被同步鎖(synchronized)持有的對(duì)象。
g、Java虛擬機(jī)內(nèi)部情況的JMXBean、JVMTI中注冊(cè)的回調(diào)、本地代碼緩存。
可以把上面的大概分成幾個(gè)方面,如下圖:
GC Roots實(shí)際上就是當(dāng)前JVM必須要的對(duì)象,可以分成三類。
第一類是JVM線程里面直接引用的對(duì)象,相當(dāng)于正在執(zhí)行的方法里面的對(duì)象,這些肯定是必須存活的。
第二類是設(shè)置的一些靜態(tài)常量,比如我們?cè)陬惱锩嬗胹tatic final修飾的一些對(duì)象,這類對(duì)象至jvm啟動(dòng)到結(jié)束都會(huì)一直存在。
第三類就是JVM本身所需要的對(duì)象,這類對(duì)象肯定不能被回收。
03Java的引用
可達(dá)性分析就是根據(jù)引用來(lái)判斷的,那么Java中有哪些引用呢?一共分4類引用:
a、強(qiáng)引用:常見(jiàn)的引用賦值,垃圾收集器不回收。ObjectA a=new ObjectA();
b、軟引用:還有用,但非必須。在系統(tǒng)將要發(fā)生內(nèi)存溢出前,把他們列為回收范圍進(jìn)行二次回收,JDK1.2后SoftReference類實(shí)現(xiàn)。
c、弱引用:非必須,比軟引用更弱。下次垃圾收集器無(wú)論內(nèi)存是否足夠,均回收。JDK1.2后WeakReference類實(shí)現(xiàn)。
d、虛引用:最弱引用關(guān)系,虛引用不影響對(duì)象的生存,也無(wú)法通過(guò)虛引用來(lái)取得對(duì)象實(shí)例。唯一作用是可以在垃圾收集器回收前收到一個(gè)系統(tǒng)通知。JDK1.2后PhantomReference類實(shí)現(xiàn)。
對(duì)比如下圖:
后面三個(gè)引用我們平時(shí)使用幾乎沒(méi)有,多在一些源碼中出現(xiàn),依靠3個(gè)類實(shí)現(xiàn):SoftReference、WeakReference、PhantomReference。在看到這三個(gè)類的時(shí)候能知道對(duì)應(yīng)的含義。
04兩次標(biāo)記
當(dāng)一個(gè)對(duì)象被標(biāo)記為不可達(dá)對(duì)象的時(shí)候并不一定是馬上被回收的。如果對(duì)象重寫(xiě)了finalize()方法,并且finalize()方法還沒(méi)有被執(zhí)行過(guò)(finalize()方法只會(huì)被執(zhí)行一次),那么這個(gè)對(duì)象會(huì)被放入F-Queue隊(duì)列里面。會(huì)有一個(gè)Finalizer線程去執(zhí)行隊(duì)列里面對(duì)象的finalize()。如果finalize()方法把這個(gè)對(duì)象重新賦值給了其他變量,就叫做逃脫成功。
垃圾收集器會(huì)對(duì)F-Queue隊(duì)列里的對(duì)象進(jìn)行第二次標(biāo)記,如果在上一步中成功逃脫的就會(huì)移除即將回收的集合。
對(duì)于逃脫的對(duì)象,在下次被標(biāo)記成不可達(dá)對(duì)象時(shí),就會(huì)被直接回收,因?yàn)閒inalize()方法已經(jīng)執(zhí)行過(guò)一次了。
Java程序員日常學(xué)習(xí)筆記,如理解有誤歡迎各位交流討論!
總結(jié)
以上是生活随笔為你收集整理的java判断对象已死_Java的JVM判断对象已死的基本算法分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 《楚乔传》星儿恢复记忆 楚乔真实身份曝光
- 下一篇: 甲醛检测一次多少钱啊?