1. 程式人生 > 其它 >JVM垃圾回收判斷物件存活的演算法

JVM垃圾回收判斷物件存活的演算法

JVM垃圾回收判斷物件存活的演算法

  • 引用計演算法

    定義:在物件中新增一個引用計數器,每當有一個地方應用它時,計數器值就加一;當引用失效時,計數器值減一;任何時刻計數器為零的物件就是不可能再被使用的。

    缺點:主流Java虛擬機器裡面都沒有選用引用計數演算法來管理記憶體。主要原因是這種演算法有很多例外的情況要考慮,譬如單純的引用計數就很難解決物件之間迴圈引用(依賴)的問題。

  • 可達分析演算法

    定義:這個演算法的基本思路就是通過一系列稱為“GC Roots”的根物件作為起始節點集,從這些節點開始,根據引用關係向下搜尋,搜尋過程所走過的路徑稱為“引用鏈”(Reference Chain),如果某物件到GC Roots間沒有任何引用鏈相連,或者用圖論的話來   說就是從 GC Roots到這個物件不可達時,證明此物件是不可能再被引用的。

    Java體系固定作為GC Roots的物件包括以下幾種

    1、在虛擬機器棧(棧幀中的本地變量表)中引用的物件,譬如各個執行緒被呼叫的方法堆疊中使用到的引數、區域性變數、臨時變數等

    2、在方法區中類靜態屬性引用的物件,譬如Java類的引用型別靜態變數

    3、在方法區常量引用的物件,譬如字串常量池(String Table)裡的引用

    4、在本地方法棧中JNI(通常所說的Native方法)引用的物件

    5、Java虛擬機器內部的引用,如基本資料型別對應的Class物件,一些常駐的異常物件(比如NullPointException、OutOfMemoryError)等,還有系統類載入器

    6、所有被同步鎖(synchronized關鍵字)持有的物件

    7、反映Java虛擬機器內部情況的JMXBean、JVMTI中註冊的回撥、原生代碼快取等。

    除了這些固定的GC Roots集合以外,根據使用者所選用的垃圾收集器以及當前回收的記憶體區域不同,還可以有其他物件“臨時性”的加入。譬如分代收集和區域性回收(Partial GC),如果只針對Java堆中某一塊區域發起垃圾收集時,必須考慮到記憶體區域是虛擬機器自己實現細節,不是孤立封閉的,所以某個區域裡的物件完全可能被堆中其他物件引用。