Java垃圾收集方法

對象是否已死

引用計數算法

給對象添加一個引用計數器,每當一個地方要引用它時,計數器的值就加一;當引用失效,計數器值就減一。
看似合理,但是沒法解決對象間互相引用的問題。

可達性分析算法

通過“GC Roots”的對象作爲起始點,向下搜索,當一個對象到GC Roots沒有任何引用鏈相連,則說明對象不可達,即對象不可用。
可以作爲GC Roots 的對象包括:

  • 棧幀中引用的對象
  • 方法區靜態類屬性引用的對象
  • 方法區中常量引用的對象
  • 本地方法棧引用的對象

引用

如果reference類型的數據中存儲的數值代表的是另一塊內存的起始地址,就稱這塊內存代表着一個引用:

  • 強引用(Strong Reference):只要強引用在,垃圾回收機制永遠不會回收掉被引用的對象
  • 軟引用(SoftReference):將要發生內存溢出之前,會把這些對象列入回收範圍進行第二次回收。若這次回收還沒有足夠的內存,才拋出溢出異常
  • 弱引用(Weak Reference):只要發生垃圾回收,就把他幹掉
  • 虛引用(Phantom Reference):其存在與否無影響,只是在回收時會反饋一個信息

對象的自救

一個對象要真正被判死刑,需經歷兩次標記:

  • 若對象不可達,判斷對象是否有必要執行finalize()方法:
    沒有必要執行:
    ①沒有覆蓋此方法
    ②此方法已經被調用過
  • 若執行,則放在一個F-Queue隊列中,稍後由一個優先級低的Finaizer線程執行它,只要對象在被執行之前重新與引用臉上的任何一個對象建立關聯即可。
    但是隻有一次自救機會

回收方法區

條件:

  • 該類所有實例都被收回
  • 加載該類的ClassLoader已經被回收
  • 該類對應的Java.lang.Class對象沒有在任何地方被引用,無法在任何地方通過反射訪問該類的方法。

垃圾收集

標記-清楚算法

標記要回收的對象,標記完後統一回收所有被標記的對象
不足:①效率,標記和清楚效率都不高
②空間,清楚產生大量內部碎片

複製算法

把內存分成兩半,每次把其中存活的對象複製到另一半空白處,然後把原來那半全部幹掉
缺點:內存只剩下了一半,浪費太多(所以現實中,並不是按照1:1)

標記-整理算法

讓存活的對象向一端移動,把不是邊界的部分清除掉

分代收集算法

  • 新生代:複製算法,因爲有大量對象被幹掉
  • 老年代:標記-清理 或 標記-整理 ,因爲存活率高,並且沒有額外空間對它進行擔保。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章