1. 程式人生 > >Java 垃圾回收演算法

Java 垃圾回收演算法

java語言引入了記憶體回收機制,對於C++程式設計師記憶體管理的問題迎刃而解。 為什麼需要進行垃圾回收,如果不回收記憶體早晚回耗盡。既然要回收,哪些記憶體是需要回收的,什麼演算法判斷是否需要回收,就成了關鍵問題。 首先來看一下判斷物件是否存活的演算法,因為垃圾回收只回收非存活的物件,所以要先判斷出物件是否存活。

1、引用計數演算法     堆中每個物件例項都有一個引用計數,當一個物件被建立時,就將該物件例項分配給一個變數,該變數計數設定成1。當其他任何物件被賦值為這個物件的引用時,計數加1。     當這個物件例項的引用超過了生命週期或者被設定成一個新值時,計數減1。任何引用計數器為0的物件,會當作垃圾收集。     優點:執行速度快。     缺點:無法檢測出迴圈引用。

2、可達性分析演算法     從一個節點 GC ROOT 開始,尋找對應的引用節點,依次往下尋找。當所有的引用節點尋找完畢,剩下的節點則被認為是沒有被引用到的節點,即無用節點,無用節點認為是可回收的物件。     什麼樣的物件可以作為 GC ROOT 物件呢:         1、虛擬機器棧中引用的物件。         2、方法區中類靜態屬性引用的物件。         3、方法區中常量引用的物件。         4、本地方法棧中JNI引用的物件。

即使被可達性分析演算法判定為無用物件,也要經過兩次標記之後才能真正死亡: 第一次標記: 如果物件在經過可達性分析演算法判斷沒有與GC ROOT相連結的引用鏈,會被第一次標記。 第二次標記: 第一次標記完成以後,會進行第二輪篩選。篩選的條件是此物件是否有必要執行finalize()方法,在finalize()方法中沒有重新與引用鏈建立關聯關係的,將被進行第二次標記。

第二次標記成功的物件將真的會被回收,如果物件在finalize()方法中重新與引用鏈建立了關聯關係,那麼將不會被回收。