1. 程式人生 > >Java記憶體回收之可達性分析演算法

Java記憶體回收之可達性分析演算法

Java記憶體回收時的可達性分析演算法

也稱為傳遞跟蹤演算法;

Java中,是通過可達性分析演算法來判斷物件是否存活的。

1:演算法的思路 通過一系列的“GC Roots”物件作為起點,開始向下搜尋 搜尋所走過的路徑稱為引用鏈; 當一個物件到GC Roots沒有任何引用鏈時(即從GC Roots到這個物件不可達),則證明該物件不可用

Java中的物件都連結在一個個根節點上,所以記憶體中會有許多的根節點(即GC Roots),記憶體回收的時候最費時間的就是找到這些根節點。Java虛擬機器中有一種表OopMap記錄了部分根節點和物件的連結關係,通過它可以進行列舉根節點。沒有就全部是因為太耗記憶體。但在程式執行的過程中一直都有物件的建立,消亡,所以該表一直都在變化,所以必須在某個時刻查表,這個時間點成為安全點。根據表找到物件的根節點,通過引用鏈找到該物件判斷它是否GC可達。 在這裡插入圖片描述

2:瞭解下哪些地方存在GC Roots呢 (1)虛擬機器棧中的引用物件 (2)方法去中靜態屬性引用的物件 (3)方法區中常量引用的物件 (4)本地方法棧native方法引用的物件

3:判斷物件的消亡與否 真正判一個物件的死亡需要經歷兩次標記過程 (1)第一次標記:在可達性分析後發現GC Roots到物件不可達時第一次標記,並且進行一次篩選 此物件是否有必要執行finalize方法 有必要執行的情況有:該對物件重寫了finalize方法;jvm建立了低優先順序的執行緒呼叫了該物件的finalize方法 沒有必要執行的情況有:該物件沒有重寫finalize方法:finalize方法已經被jvm呼叫過了 (2)第二次標記:如果物件在finalize方法中與GC Roots重新取得連線,第二次標記就會把他從回收集合中剔除;否則物件就可以被回收了

4:可達性分析演算法的問題: 1:耗時長:找到根節點以及在大量資料中逐個檢查引用耗費大量時間 2:GC停頓:就是上文提到的安全點問題,這個時間點會導致Java所有執行執行緒的停頓

安全點的選定不宜過少,否則GC等待時間太長;也不能過多,否則增大執行的負荷

5:在安全點位置如何讓GC發生時,其他執行緒都停止執行 (1)搶斷式中斷 在GC發生時,首先中斷所有執行緒 如果發現不在安全點上的執行緒美酒恢復讓其執行到安全點上 (2)主動式中斷 在GC發生時,不直接操作執行緒的中斷,而是設定一個標誌 讓各執行緒執行時主動去輪詢這個標誌,發現中斷標誌為真時就自己中斷掛起 而輪詢標誌的地方和Safepoint是重合的;