1. 程式人生 > >Java虛擬機-垃圾收集器

Java虛擬機-垃圾收集器

回收 虛擬 需要 狀態 分支 內存 優先 並且 即將

  垃圾收集器(Garbage Collection, GC)的誕生引導出了三個問題:

  哪些內存需要回收?

  什麽時候回收?

  如何回收?

  對於線程獨占的三個區域(程序計數器、虛擬機棧、本地方法棧)不用過多的考慮垃圾回收的問題,因為他們隨著線程創建而生,隨著線程結束而消失。然而Java堆和方法區則不一樣,一個接口的多個實現類需要的內存可能不一樣,一個方法中的多個分支需要的內存也不一樣,我們只有在程序運行的的時候才知道會創建哪些對象,這部分的內存分配是動態的,所以這也是GC所關註的方面。

  如何判斷對象已死  

  (1)引用計數法:給對象添加一個引用計數器,每當一個地方引用它,就加一,引用失效,就減1。引用計數法實現比較簡單,判定效率也高,但是往往有這樣一種情況,兩個對象相互引用,除此之外別無它用,這樣算不算垃圾對象?在經過驗證之後發現,這樣的對象也會被GC回收,因此我們可以判定,Java虛擬機的GC采用的並不是這種機制。

  (2)可達性分析法:這個算法的基本思想就是通過一系列的稱為“GC Roots”的對象作為起始點,從這些結點開始向下搜索,搜索走過的路徑稱為引用鏈。當一個對象沒有任何引用鏈相連時,我們可以得到這個對象是不可用的,於是這個對象會被判定是可回收的對象。

  生存還是死亡

  即時在可達性分析法中不可達的對象,也並非是“非死不可”的對象,這時候他們暫時處於一個“緩刑”狀態,要想真正的宣告一個對象的死亡,至少經歷兩個標記過程:如果對象不可達,那麽它將會被第一次標記並且進行一次篩選,篩選的條件是此對象是否有必要執行finalize()方法,如果(1)沒有這種方法(2)已經執行過這種方法,那麽就可以看做“沒有必要執行”。如果對象被判定有必要執行finalize方法,那麽這個對象將會被放在一個叫F-Queue的隊列之中,並在稍後由一個虛擬機自動建立、低優先級的Finalize線程去執行它。如果對象在這次處理中拯救了自己,和其他建立了聯系,那麽就會被移除“即將回收”集合。如果還是沒有任何聯系,那就會被真正回收掉。

  

  

Java虛擬機-垃圾收集器