如何判斷對象是否要回收
Java堆裏存放着幾乎所有的對象實例,垃圾收集器在回收對象前,第一件事就是確認這個對象是否還在被使用。
判斷對象是否要回收的算法有兩種,引用計數算法和可達性分析算法。
引用計數算法
引用計數算法 是給對象添加一個引用計數器,每當有一個地方引用它時,計數器值就加 1,當引用失效時,計數器值就減 1,任何時刻計數器爲 0 的對象就是不可能再被使用的。
java虛擬機裏面沒有選用引用計數算法來管理內存,因爲最主要的原因是它很難解決對象之間相互引用的問題。
如下代碼:
public class ReferenceCountingGC {
ReferenceCountingGC referenceCountingGC;
public static void main(String []args){
ReferenceCountingGC rc1=new ReferenceCountingGC();
ReferenceCountingGC rc2=new ReferenceCountingGC();
rc1.referenceCountingGC=rc2;
rc2.referenceCountingGC=rc1;
}
}
以上兩個對象相互引用,導致它們的引用計數都不爲0,導致兩個對象無法被回收。
可達性分析算法
Java中是通過可達性分析(Reachability Analysis)算法來判定對象是否存活的。
該算法是通過一系列的稱爲"GC Roots" 的對象 作爲起始點,從GC Roots 開始向下搜索,搜索所走過的路徑稱爲引用鏈(Reference Chain),當一個對象到“GC Roots” 沒有任何引用鏈相連時,則證明該對象是不可用的。
如上圖,右邊幾個對象雖然有被引用,但是沒有到達GC Root 所以會被判定爲是可回收的對象。
可作爲GC Root 的對象
1.虛擬機棧本地變量表中引用的對象。
2.方法區中類靜態屬性引用的對象。
3.方法區中常量引用的對象。
4.Native方法引用的對象。
參考
學習摘抄於深入理解Java虛擬機