日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

contentwindow无法搜索对象_面试官:讲一下Jvm中如何判断对象的生死?

發(fā)布時間:2024/4/11 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 contentwindow无法搜索对象_面试官:讲一下Jvm中如何判断对象的生死? 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

但凡問到 JVM(Java 虛擬機)通常有 99% 的概率一定會問,在 JVM 中如何判斷一個對象的生死狀態(tài)?

判斷對象的生死狀態(tài)的算法有以下幾個:

1、引用計數(shù)器算法

引用計算器判斷對象是否存活的算法是這樣的:給每一個對象設(shè)置一個引用計數(shù)器,每當(dāng)有一個地方引用這個對象的時候,計數(shù)器就加1,與之相反,每當(dāng)引用失效的時候就減1。

優(yōu)點:實現(xiàn)簡單、性能高。

缺點:增減處理頻繁消耗cpu計算、計數(shù)器占用很多位浪費空間、最重要的缺點是無法解決循環(huán)引用的問題。

因為引用計數(shù)器算法很難解決循環(huán)引用的問題,所以主流的Java虛擬機都沒有使用引用計數(shù)器算法來管理內(nèi)存。

來看一段循環(huán)引用的代碼:

public

運行的結(jié)果:

開始:117 M
運行中:96 M
結(jié)束:119 M

從結(jié)果可以看出,虛擬機并沒有因為相互引用就不回收它們,也側(cè)面說明了虛擬機并不是使用引用計數(shù)器實現(xiàn)的。

2、可達(dá)性分析算法

在主流的語言的主流實現(xiàn)中,比如Java、C#、甚至是古老的Lisp都是使用的可達(dá)性分析算法來判斷對象是否存活的。

這個算法的核心思路就是通過一些列的“GC Roots”對象作為起始點,從這些對象開始往下搜索,搜索所經(jīng)過的路徑稱之為“引用鏈”。

當(dāng)一個對象到GC Roots沒有任何引用鏈相連的時候,證明此對象是可以被回收的。如下圖所示:

在Java中,可作為GC Roots對象的列表:

  • Java虛擬機棧中的引用對象。
  • 本地方法棧中JNI(既一般說的Native方法)引用的對象。
  • 方法區(qū)中類靜態(tài)常量的引用對象。
  • 方法區(qū)中常量的引用對象。

對象生死與引用的關(guān)系

從上面的兩種算法來看,不管是引用計數(shù)法還是可達(dá)性分析算法都與對象的“引用”有關(guān),這說明:對象的引用決定了對象的生死。那對象的引用都有那些呢?

在JDK1.2之前,引用的定義很傳統(tǒng):如果reference類型的數(shù)據(jù)中存儲的數(shù)值代表的是另一塊內(nèi)存的起始地址,就稱這塊內(nèi)存代表著一塊引用。

這樣的定義很純粹,但是也很狹隘,這種情況下一個對象要么被引用,要么沒引用,對于介于兩者之間的對象顯得無能為力。

JDK1.2之后對引用進(jìn)行了擴充,將引用分為:

  • 強引用(Strong Reference)
  • 軟引用(Soft Reference)
  • 弱引用(Weak Reference)
  • 虛引用(Phantom Reference)

這也就是文章開頭第一個問題的答案,對象不是非生即死的,當(dāng)空間還足夠時,還可以保留這些對象,如果空間不足時,再拋棄這些對象。很多緩存功能的實現(xiàn)也符合這樣的場景。

強引用、軟引用、弱引用、虛引用,這4種引用的強度是依次遞減的。

強引用:在代碼中普遍存在的,類似“Object obj = new Object()”這類引用,只要強引用還在,垃圾收集器永遠(yuǎn)不會回收掉被引用的對象。

軟引用:是一種相對強引用弱化一些的引用,可以讓對象豁免一些垃圾收集,只有當(dāng)jvm認(rèn)為內(nèi)存不足時,才會去試圖回收軟引用指向的對象。jvm會確保在拋出OutOfMemoryError之前,清理軟引用指向的對象。

弱引用:非必需對象,但它的強度比軟引用更弱,被弱引用關(guān)聯(lián)的對象只能生存到下一次垃圾收集發(fā)生之前。

虛引用:也稱為幽靈引用或幻影引用,是最弱的一種引用關(guān)系,無法通過虛引用來獲取一個對象實例,為對象設(shè)置虛引用的目的只有一個,就是當(dāng)著個對象被收集器回收時收到一條系統(tǒng)通知。

死亡標(biāo)記與拯救

在可達(dá)性算法中不可達(dá)的對象,并不是“非死不可”的,要真正宣告一個對象死亡,至少要經(jīng)歷兩次標(biāo)記的過程。

如果對象在進(jìn)行可達(dá)性分析之后,沒有與GC Roots相連接的引用鏈,它會被第一次標(biāo)記,并進(jìn)行篩選,篩選的條件是此對象是否有必要執(zhí)行finalize()方法。

執(zhí)行finalize()方法的兩個條件:

1、重寫了finalize()方法。

2、finalize()方法之前沒被調(diào)用過,因為對象的finalize()方法只能被執(zhí)行一次。

如果滿足以上兩個條件,這個對象將會放置在F-Queue的隊列之中,并在稍后由一個虛擬機自建的、低優(yōu)先級Finalizer線程來執(zhí)行它。

對象的“自我拯救”

finalize()方法是對象脫離死亡命運最后的機會,如果對象在finalize()方法中重新與引用鏈上的任何一個對象建立關(guān)聯(lián)即可,比如把自己(this關(guān)鍵字)賦值給某個類變量或?qū)ο蟮某蓡T變量。

來看具體的實現(xiàn)代碼:

public

執(zhí)行的結(jié)果:

執(zhí)行finalize方法
我還活著
我已經(jīng)死了

從結(jié)果可以看出,任何對象的finalize()方法都只會被系統(tǒng)調(diào)用一次。

不建議使用finalize()方法來拯救對象,原因如下:

1、對象的finalize()只能執(zhí)行一次。

2、它的運行代價高昂。

3、不確定性大。

4、無法保證各個對象的調(diào)用順序。

原文鏈接:JVM(三)對象的生死判定和算法詳解 - 王磊的博客 - 博客園

總結(jié)

以上是生活随笔為你收集整理的contentwindow无法搜索对象_面试官:讲一下Jvm中如何判断对象的生死?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。