2020久久超碰欧美精品最新亚洲欧美日韩久久精品,国产福利电影一区二区三区,亚洲欧美日韩一区在线观看,亚洲国产欧美日韩欧美特级,亚洲欧美日韩成人一区久久,欧美日韩精品一区二区三区不卡,国产欧美日韩va另类影音先锋,亚洲欧美日韩久久精品,亚洲欧美日韩国产成人精品影院,亚洲国产欧美日韩精品一区二区三区,欧美日韩国产成人高清视频,日韩久久精品国产免费观看频道,久久人人爽人人爽从片av高清,国产精品综合一区二区

首頁技術文章正文

jvm如何判斷對象已死?

更新時間:2021-10-22 來源:黑馬程序員 瀏覽量:

添加QQ(注意~~添加好友界面,選擇找人):435946716【免費】獲取《JVM核心教程:JVM從門到精通_JVM虛擬機底層原理深入教程》全套視頻教程+配套資料。


在堆里面存放著各種各類的Java對象,垃圾收集器在對堆進行垃圾回收時,首要就是判斷哪些對象還活著,哪些對象已經死去(即不被任何途徑引用的對象)。


引用計數器算法:

引用計數器算法簡單概括為:給對象添加一個引用計數器,每當有一個地方引用該對象時,計數器+1,當引用失效時,計數器-1,任何時刻,當計數器為0的時候,該對象不再被引用。客觀的說,引用計數器的實現簡單,判定效率也高,大部分場景下是一個不錯的選擇。但是,當前主流的Jvm均沒有采用標記清除算法,原因在于,它很難解決對象之間互相循環調用的情況。


可達性分析算法:

在主流的商用程序語言(如C#, Java)的主流實現中,都是通過可達性分析來判斷對象是否存活,這個算法的思想就是通過一系列的成為"GC Roots"的對象作為起始點,從這些節點開始向下搜索,搜索所走過的路徑成為引用鏈,當一個對象到"GC Roots"沒有任何引用鏈相連,則證明此對象是不可用的。

可達性分析算法

如圖所示,雖然Obj5, Obj6, Obj7互有關聯,但是他們到GC root沒有任何引用鏈,所以判定為需要被回收的對象。

常說的GC(Garbage Collector) roots,特指的是垃圾收集器(Garbage Collector)的對象,GC會收集那些不是GC roots且沒有被GC roots引用的對象。

在Java中,可以作為GC Roots的對象包括下面幾種:

·虛擬機棧中引用的對象;

·方法區中類靜態屬性引用的對象;

·方法區中的常量引用的對象;

·本地方法棧中JNI(即一般說的Native方法)的引用的對象;

GC Roots

再談引用

無論是通過引用計數器判斷的引用數量,還是通過可達性分析判斷出的引用鏈是否可達,判定對象是否存活都跟引用有關。在JDK1.2以前,引用被定義為當一個reference類型的數據代表的是另外一塊內存的起始地址,該類型的數據被稱之為引用,這種定義很純粹,但是也很狹隘,一個對象在這種定義下只有被引用和沒有被引用兩種狀態。對于描述一些“食之無味,棄之可惜”的對象就顯得無能為力。我們希望能描述這類對象,當內存足夠的時候,將它存放在內存中,當內存空間進行垃圾回收后顯得還是內存緊張時,可以回收這部分對象,很多系統的緩存功能都符合這樣的應用場景。因此在JDK1.2以后對引用進行重新的擴充,分為強引用,軟引用,弱引用,虛引用4中,這四種引用的強度依次遞減。


強引用:

強引用是在代碼中普遍存在的,類似于Object obj = new Object(),只要強引用一直存在,垃圾收集器就永遠不會回收被引用的對象。


軟引用:

軟引用用來描述一些還有用但并非必須的對象,對于軟引用關聯著的對象,當內存溢出異常發生之前,通過垃圾回收進行二次回收。如果二次回收完成之后,系統內存依然不夠,才會拋出內存溢出異常,在jdk1,2以后用SoftReference類來實現軟引用。


弱引用:

弱引用也是用來描述非必須對象的,但是它的強度相比于軟引用來說更弱一些,它僅僅能生存到下一次垃圾回收之前。當垃圾收集時,無論內存是否足夠,弱引用的對象都要被回收,在jdk1.2以后用WeakReference類來實現弱引用


虛引用:

虛引用是最弱的一種引用關系,一個對象是否有虛引用的存在,完全不會對其生存時間構成影響,也無法通過一個虛引用來獲取一個實例對象。為一個對象設置弱引用的唯一目的就是該對象在垃圾回收時受到一個系統通知,Jdk1,2以后用PhantomReference實現虛引用。

虛引用


生存還是死亡?

即使在可達性分析中,沒有引用鏈到達GC Roots,也并非是“非死不可”的。這個時候對象處于緩刑階段,要正式宣告死亡,至少要經歷兩次標記的過程。如果對象在進行可達性分析后發現沒有與GC Roots相連接的引用鏈,那它將會被第一次標記并進行一次篩選,篩選的條件是此對象是否要執行finalize()方法,當對象么有覆蓋finalize()方法,或者finalize()方法已經被虛擬機調用過,虛擬機將這兩種情況都視為不必要執行finalize()方法。

如果該對象被判定要執行finalize()方法,那么這個對象會被放在一個叫F-Queue的隊列中,并在稍后有一個虛擬機自行創建的,優先級較低的線程去執行它,這里的執行是指會觸發finalize()方法,但并不會等待它執行結束。這樣做的原因是如果一個對象在執行finalize()時非常緩慢,或者執行了死循環,這樣就會導致F-Queue中的其他對象處于等待中,嚴重的會導致整個垃圾回收系統崩潰。finalize()是對象逃脫死亡的最后一次機會,稍后GC將對F-Queue中的對象進行二次標記,如果對象要在finalize()中拯救自己的話,只能重新與引用鏈上的任意一個對象建立關聯即可,比如把對象自己(this關鍵字)賦值給其他成員變量或者對象,那在第二次標記時就被移出即將回收的集合,如果沒有關聯上,基本可以確定要被回收了。



猜你喜歡

jvm垃圾收集器有哪些?深度講解

Java中的垃圾回收機制是什么?哪些對象會被回收?

垃圾收集算法有哪些?圖文詳細介紹

JVM組成部分和作用詳細介紹

黑馬程序員JavaEE高手班課程

分享到:
在線咨詢 我要報名
和我們在線交談!