這一篇應該是在垃圾收集器那一篇之前的,當時由於有些地方不太理解,一直擱置了,幾天寫出來,仍然有很多自己揣測的地方,看的朋友可以有選擇的採納。
前面垃圾收集器概述的筆記中已經寫過,通過可達性分析算法——是否有到
達GC Roots的引用鏈來判斷,對象是否可以被回收。
對象之間的引用在類的成員變量初始化以及類的方法中都會出現,如果逐個遍歷,會消耗很多時間。
虛擬機是怎麼做的呢?使用一組OopMap來記錄對象在棧中的引用地址,這樣,HotSpot就可以快速找到GC Roots的對象集合。
(Oop:Ordinary Object Pointer,普通對象指針)
另外,如果在進行判斷分析的時候,有新的引用產生怎麼辦呢?
這就要求在虛擬機執行垃圾收集的時候,需要將所有虛擬機暫停(「Stop the world」),以保持快照的一致性。
但是如果積攢了比較多的對象集中進行分析,那麼這個暫停的時間就會比較長,一次收集的時間就會比較多。
如果通過增加垃圾收集頻次,減少每次垃圾收集分析工作量,那麼垃圾收集佔用總的時間也不少。
安全點:由於為每一條指令都生成OopMap需要大量的空間,所以只再特定的位置記錄這些信息,這些位置成為安全點。
安全點的選定是以「是否具有讓程序長時間執行的特徵為標準」進行選定。
長時間執行的的最明顯特徵是指令序列復用。
另外,虛擬機有兩種中斷方式。
1. 搶先式中斷:由虛擬機發起,所有線程全部中斷,不在安全點上的線程,恢復運行至安全點上。
2. 主動式中斷:由線程去輪詢是否中斷的標誌位,發現標識,就自己將線程暫停掛起。
HotSpot採用的是主動式中斷的方式。
安全區域(Safe Region):在一段代碼片段當中,引用關係不會發生變化。
作用:專門用來處理當進行垃圾收集的時候,沒有分配CPU時間的程序,比如線程處於Sleep狀態,這些線程沒辦法響應JVM的暫停要求,對於這種狀況,單獨設置了一個安全區域。
基本思路:1. 當線程執行到安全區域中的代碼時,標識自己進入了安全區域。
2. 當線程準備離開安全區域的時候,檢查垃圾收集是否完成,如果結束了,線程繼續執行;如果沒結束,就等到結束之後再離開安全區域。
喜歡文章或想一起學習的朋友可以關注我,給我點讚,我將會持續更新,有什麼疑問或文中有不當之處請給我留言,真誠地希望能與大家一起交流探討,學習進步。