GC判定對象已死的2種方法
引用計數法
給對象中添加一個引用計數器,每當有一個地方引用它時,計數器值就加1;當引用失效時,計數器值就減1;Java語言中沒有選用引用計數算法來管理內存,其中最主要的原因是它很難解決對象之間的相互循環引用的問題。
可達性分析算法
這個算法的基本思路就是通過一系列的名為
“GC Roots”
的對象作為起始點,從這些節點開始向下搜索,搜索所走過的路徑稱為引用鏈(Reference Chain)
,當一個對象到GC Roots沒有任何引用鏈相連(用圖論的話來說就是從GC Roots到這個對象不可達)時,則證明此對象是不可用的。
在Java語言里,可作為GC Roots
的對象包括下面幾種:
1、虛擬機棧(棧幀中的本地變量表)中引用的對象
2、本地方法棧(Native 方法)中引用的對象
3、方法區中類靜態屬性引用的對象
4、方法區中常量引用的對象
5、所有被同步鎖(synchronized關鍵字)持有的對象
6、Java虛擬機內部的引用,如基本數據類型對應的Class對象,一些常駐的異常對象(比如 NullPointExcepiton、OutOfMemoryError)等,還有系統類加載器。
7、反映Java虛擬機內部情況的JMXBean、JVMTI中注冊的回調、本地代碼緩存等。
不可達的對象并非“非死不可”
即使在可達性分析法中不可達的對象,也并非是“非死不可”的,這時候它們暫時處于“緩刑階段”,要真正宣告一個對象死亡,至少要經歷兩次標記過程;可達性分析法中不可達的對象被第一次標記并且進行一次篩選,篩選的條件是此對象是否有必要執行 finalize 方法。當對象沒有覆蓋 finalize 方法,或 finalize 方法已經被虛擬機調用過時,虛擬機將這兩種情況視為沒有必要執行。被判定為需要執行的對象將會被放在一個隊列中進行第二次標記,除非這個對象與引用鏈上的任何一個對象建立關聯,否則就會被真的回收。
-----------------------------------------------------------------------------讀書筆記摘自 書名:深入理解Java虛擬機:JVM高級特性與最佳實踐(第3版)作者:周志明