HotSpot 對象存活判定、垃圾回收算法

在進行全局性的垃圾回收時,JVM爲保持一致性,Stop The World ,(原因在JVM性能調優已經提到過,爲了防止在某個鏈條上新產生的垃圾對象永遠無法被發現)。

枚舉根節點

當發生STW停下來之後,JVM並不需要檢查所有的引用位置,只需要知道哪裏存着這些對象,所以就有了OopMap數據結構存儲位置

安全點

OopMap內容變化的指令很多,不能爲每一條指令都生成對應的OopMap,HotSpot虛擬機是在特定位置生成了OopMap,這些位置叫做“安全點”。程序執行時只有到了安全點纔會暫停下來開始GC。一般具有“長時間執行”這個特點的指令(例如方法調用、循環跳轉、異常跳轉)纔會產生安全點。
如何在GC時讓所有線程都跑到安全點上再停頓下來?兩種方案:

(1) 搶先式中斷。(現在幾乎沒有虛擬機採用該方法)

不需要線程主動配合,在GC發生的時候就讓所有線程都中斷,如果發現哪個線程中斷的地方不在安全點上,那麼就恢復線程,然後讓它跑到安全點上。

(2) 主動式中斷

GC在需要中斷線程的時候不直接對線程操作,設置一個標誌,讓各個線程主動輪詢這個標誌,如果中斷標誌位真時就讓自己中斷。

安全區域

一段代碼片段中引用關係不會改變,在這個區域任意位置GC都是安全的

安全點完美的解決了如何進入GC問題,實際情況可能比這個更復雜,但是如果程序長時間不執行,比如線程調用的sleep方法,這時候程序無法響應JVM中斷請求這時候線程無法到達安全點,顯然JVM也不可能等待程序喚醒,這時候就需要安全區域了。

安全區域是指一段代碼片中,引用關係不會發生變化,在這個區域任何地方GC都是安全的,安全區域可以看做是安全點的一個擴展。線程執行到安全區域的代碼時,首先標識自己進入了安全區域,這樣GC時就不用管進入安全區域的線層了,線層要離開安全區域時就檢查JVM是否完成了GC
Roots枚舉,如果完成就繼續執行,如果沒有完成就等待直到收到可以安全離開的信號。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章