轉自:
http://www.java265.com/JavaCourse/202204/2841.html
下文筆者講述JVM虛擬機如何界定物件可以被回收的方法分享,如下所示:
回收就是通常我們所說的GC,那么何時我們才知道物件該回收呢 下文將一一道來,如下所示 我們都知道在java中 程式計數器、虛擬機堆疊、本地方法堆疊這三個區域隨執行緒而生,隨執行緒而滅 堆疊中的堆疊幀隨著方法的呼叫和退出而進行著入堆疊和出堆疊的程序, 每個堆疊幀分配多少記憶體在類結構確定下來時就已知的,方法結束或執行緒結束記憶體自然跟著回收了 但是java中有一個地方堆,用于存盤物件,這一部磁區域不會自動消失,她需要JVM的垃圾回收器對其進行回收 那么垃圾回收器如何界定垃圾呢?下文筆者將一一道來,如下所示
參考計數演算法
給物件添加一個參考計數器
每當一個地方參考它時候
計數器就加1,當參考失效計數器就減1
任何時刻計數器為0的物件就是不可能再被使用了
這種方法實作簡單,效率高,但是它很難解決物件的回圈參考問題:
public class Test {
private static final int a = 1024 *1024;
private Object instance = null;
public static void testGC(){
Test objectA = new Test();
Test objectB = new Test();
objectA.instance = objectB;
objectB.instance = objectA;
objectA = null;
objectB = null;
// 假如這里發生GC,objectA和objectB會不會被回收
}
}
可達性分析演算法
這個演算法的基本思路是通過一系列稱為“GC Roots”(一組必須活躍的參考)作為起始點 從這些節點開始向下搜索,搜索走過的路徑稱為參考鏈 當一個物件到GC Roots沒有任何參考鏈時候,那么證明此物件是不可用的, 在Java語言中,做作為GC Roots的物件包括以下幾種: 1)虛擬機堆疊(堆疊幀中的本地變數表)中參考的物件, 2)方法區中類靜態屬性參考的物件, 3)方法區中常量參考的物件, 4)本地方法堆疊JNI(即一般說的Native方法)參考的物件,
參考
無論是通過參考計數器演算法判斷物件的參考數量,還是通過可達性分析演算法判斷物件參考鏈是否可達,判斷物件是否可活都離不開參考 Java中將參考分為四種: 1.強參考(Strong Reference) 是指程式代碼中普遍存在的,類似“Object obj = new Object()”這類的參考,只有強參考還存在物件就不會被回收, 2.軟參考(Soft Reference) 軟參考是用來描述一些還有用但是非必須的物件,對于軟參考關聯的物件,在系統將于發生記憶體溢位例外之前,將會把這些物件列進回收范圍中進行二次回收, 3.弱參考(Weak Reference) 也是用來描述非必須物件的,強度比軟參考還弱一些,被軟參考關聯的物件只能存活到下一次記憶體回收之前, 4.虛參考(Phantom Referenece) 也成為幽靈參考和幻影參考,為一個物件設定虛參考關聯的唯一目的就是能在這個物件被回收時收到一個系統通知,
生存還是死亡
即使在可達性分析演算法中不可達的物件,也并非一定是“非死不可”的,這時候他們暫時處于“緩刑”階段,真正宣告一個物件死亡至少要經歷兩個階段: 1.如果物件在可達性分析演算法中不可達,那么它會被第一次標記并進行一次刷選,刷選的條件是是否需要執行finalize()方法 (當物件沒有覆寫finalize()或者finalize()方法已經執行過了(物件的此方法只會執行一次)),虛擬機將這兩種情況都會視為沒有必要執行) 2.如果這個物件有必要執行finalize()方法會將其放入F-Queue佇列中,稍后GC將對F-Queue佇列進行第二次標記 如果在重寫finalize()方法中將物件自己賦值給某個類變數或者物件的成員變數,那么第二次標記時候就會將它移出“即將回收”的集合 finalize()能做的作業,使用try-finally或者其他方式都能做到更好,更及時,所以不建議使用此方法,
方法區回收
永久代中回收的內容主要是兩部分:廢棄的常量和無用的類,判斷無用的類(類卸載)必須滿足三個條件: 1.該類所以的實體都已經被回收 2.加載該類的ClassLoader被回收 3.該類對應的java.lang.Class物件沒有在任何地方參考,無法在任何地方通過反射訪問該類的方法
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/499507.html
標籤:Java
下一篇:String型別函式傳遞問題
