JVM判定對象是否存活

判定對象是否存活算法

1、引用計數算法

給對象中添加一個引用計數器,每當一個地方引用它時,計數器值就+1;當引用失效時,計數器值就-1;任何時刻計數器爲0的對象就是不可能再被使用的。
優點:實現簡單,判定效率高
缺點:很難解決對象相互循環引用問題

對於JVM,並不是使用此算法,使用的是第二種算法:可達性分析算法。
如下示例看GC日誌發現,objA和objB相互引用,顯示置爲null之後,進行GC時不會因爲相互引用而不回收objA和objB,所以證明JVM並不是使用的引用計數算法。

public class ReferenceCountingGc{
    public Object instance=null;
    private static final int _1MB=1024*1024;
    
    private byte[] bigSize= new byte[2*_1MB];
    
    public static void testGC(){
        ReferenceCountingGC objA=new ReferenceCountingGC();
        ReferenceCountingGC objB=new ReferenceCountingGC();
        objA.instance=objB;
        objB.instance=objA;
        
        objA=null;
        objB=null;
        
        System.gc();
    }
}
2、可達性分析算法

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

在java語言中,可作爲GC Roots的對象包括下面幾種:

  • 虛擬機棧(棧幀中的本地變量表)中引用的對象。
  • 方法區中類靜態屬性引用的對象。
  • 方法區中常量引用的對象。
  • 本地方法棧中JNI(既一般說的Native方法)引用的對象。

JDK引用

強引用
強引用指類似Object obj=new Object()這類的引用,只要強引用還在,垃圾收集器永遠不會回收掉被引用的對象。
軟引用
軟引用是用來描述一些還有用但並非必需的對象。在系統將要發生內存溢出異常之前,將會把軟引用對象列進回收範圍進行二次回收。如果這次回收之後還是沒有足夠內存,纔會拋出內存溢出異常。在JDK1.2之後,提供了SoftReference類來實現軟引用。
弱引用
弱引用關聯的對象只能存活到下一次GC發生之前。當GC開始時,無論內存是否足夠,都會回收弱引用關聯的對象。在JDK1.2之後,提供了WeakReference類實現。
虛引用
一個對象是否有虛引用的存在,完全不會對其生存時間構成影響,也無法通過虛引用來取得一個對象實例。虛引用的唯一目的是在這個對象被GC時收到一個系統通知。在JDK1.2之後,提供了PhantomReference類實現。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章