Java物件存活判定演算法

2021-07-29 12:40:12 字數 1067 閱讀 9408

1、引用計數演算法

給物件新增乙個引用計數器,每當有乙個地方引用它時,計數器值就加1;當引用失效時,計數器值就減1;任何時刻計數器為0的物件就是不可能再被使用的。

優點:實現簡單、判定效率也很高;

缺點:它很難解決物件之間互相迴圈引用的問題。

2、可達性分析演算法

這個演算法的基本思想就是通過一系列的稱為「gc roots」的物件作為起始點,從這些節點開始向下搜尋,搜尋所走過的路徑稱為引用鏈(reference chain),當乙個物件到gc roots沒有任何引用鏈相連(用圖論的話來說,就是從gc roots到這個物件不可達)時,則證明此物件是不可用的。

物件的生存與死亡

(這部分在書中講得特別精彩,可以參照書中的內容來理解,下面的內容摘抄自原文p66-68)

即使在可達性分析演算法中不可達的物件,也並非是「非死不可」的,這時候它們暫時處於「緩刑」階段,要真正宣告乙個物件死亡,至少要經歷兩次標記過程:如果物件在進行可達性分析後發現沒有與gc roots相連線的引用鏈,那它將會被第一次標記並且進行一次篩選,篩選的條件是此物件是否有必要執行finalize()方法。當物件沒有覆蓋finalize()方法,或者finalize()方法已經被虛擬機器呼叫過,虛擬機器將這兩種情況都視為「沒有必要執行」。

如果這個物件被判定為有必要執行finalize()方法,那麼這個物件將會放置在乙個叫做f-queue的佇列之中,並在稍後由乙個由虛擬機器自動建立的、低優先順序的finalizer執行緒去執行它。這裡所謂的「執行」是指虛擬機會觸發這個方法,但並不承諾會等待它執行結束,這樣做的原因是,如果乙個物件在finalize()方法中執行緩慢,或者發生了死迴圈(更極端的情況),將很可能會導致f-queue佇列中其他物件永久處於等待,甚至導致整個記憶體**系統崩潰。finalize()方法是物件逃脫死亡命運的最後一次機會,稍後gc將對f-queue中的物件進行第二次小規模的標記,如果物件要在finalize()中成功拯救自己——只要重新與引用鏈上的任何乙個物件建立關聯即可,譬如把自己(this關鍵字)賦值給某個類變數或者物件的成員變數,那在第二次標記時它將被移除出「即將**」的集合;如果物件這時候還沒有逃脫,那基本上它就真的被**了。

物件存活判定演算法 判斷物件是否活著

物件被jvm收集的前提是該物件已經被jvm標記為了 死去 的物件。引用計數法 引用計數法的基本概念是 給物件新增乙個引用計數器,每當有乙個地方引用了該物件,計數器就加1 當引用失效,計數器就減1 任何時刻的計數器為0的物件就是不可能在被使用的物件。雖然是乙個實現簡單有效的演算法,但是jvm已經很少使...

如何判斷Java物件是否存活

該種方法是每乙個物件有乙個引用計數屬性,新增乙個引用時計數加1,引用釋放時計數減1,計數為0時表示沒用引用,則代表該物件可以 這種方法簡單,但是無法解決物件相互迴圈引用的問題。該種方法是從gc roots開始向下搜尋,搜尋所走過的路徑為引用鏈。當乙個物件到gc roots沒用任何引用鏈時,則證明此物...

jvm判斷物件存活

我們在編碼的過程當中,堆的空間的利用率是有限制的,假設我們的堆空間已經快要觸發gc,那麼大家有沒有想過,gc進行 的時候,到底哪一類的物件才能被 的標準是那些,好的,廢話不多,直接開始 引用計數法 可達性分析演算法 根搜尋法gs roots演算法 引用計數法的圖例如下 給物件中新增乙個引用計數器,每...