垃圾收集器在對堆進行回收前,需要先判斷堆中哪些對象是“活著”的,哪些對象是“死了”的。
1.引用計數(shù)法
給對象添加一個引用計數(shù)器,每當有一個地方引用它時,計數(shù)器加1,當引用失效時,計數(shù)器減1。任何時刻計數(shù)器為0的對象就是不可能再被使用的。
引用計數(shù)器實現(xiàn)簡單,效率高。但是主流的JVM并沒有使用引用計數(shù)法來管理內(nèi)存,主要原因是它難以解決對象之間循環(huán)引用的問題。例如,對象objA和對象objB都有字段instance,令objA.instance=objB,objB.instance=objA,除此之外這兩個對象再無任何引用,實際上這兩個對象再無可能被訪問,但是因為兩個對象之間互相引用,兩者的引用計數(shù)器都不為0,引用計數(shù)法無法回收這兩個對象。
2.可達性分析算法
JVM的主流實現(xiàn)是通過可達性分析來判斷對象是否存活的。這個算法的基本思路是通過一系列的稱為“GC Roots”的對象作為起點,從這些起點開始向下搜索,搜索所走過的路徑稱為引用鏈,當一個對象到GC Roots沒有任何引用鏈時,證明此對象是不可用的,將會成為可回收的對象。
java中,可作為GC Roots的對象包括:
3.引用
引用可以分為強引用(Strong Reference)、軟引用(Soft Reference)、弱引用(Weak Reference)和虛引用(Phantom Reference)四種。
// PRime holds a strong referenceCounter counter = new Counter();// soft reference variable has SoftReference to Counter Object primeSoftReference soft = new SoftReference(counter) ; // now Counter object is eligible for garbage collection // but only be collected when JVM absolutely needs memoryprime = null;
Counter counter = new Counter(); // weak referenceWeakReference weak = new WeakReference(counter);// now Counter object is eligible for garbage collectioncounter = null;
4.生存還是死亡
一個對象真正死亡,至少要經(jīng)歷兩次標記過程。如果對象在可達性分析后發(fā)現(xiàn)沒有與GC Roots相連接的引用鏈,那它將會被第一次標記并且進行一次篩選,篩選條件是該對象是否有必要執(zhí)行finalize()方法。當對象沒有覆蓋finalize()方法或者finalize()方法已經(jīng)被虛擬機執(zhí)行過,則認為沒有必要執(zhí)行。如果對象有必要執(zhí)行finalize()方法,那么該對象會被放置到一個叫F-Queue的隊列中,并稍后由一個JVM自動建立的、低優(yōu)先級的Finalizer線程去執(zhí)行。這里的“執(zhí)行”指虛擬機有機會促發(fā)這個方法,但不承諾會等待其運行結(jié)束。finalize()方法是對象逃脫死亡的最后一次機會,稍后GC將對F-Queue中的對象進行第二次標記,如果對象在finalize()中將自己重新與引用鏈上的任意對象建立關聯(lián)(例如將自己this賦值給某個類變量或?qū)ο蟮某蓡T變量),那么第二次標記是將其移出需要回收的集合,否則該對象就真的會被回收了。
5.回收方法區(qū)
新聞熱點
疑難解答