HotSpot虛擬機的算法實現——深入理解Java虛擬機(八)

前言

   看的人越來越多,我也有必要致敬一下“深入Java虛擬機“這本書了,小瘋子每天更新的目錄是按着這樣的節奏來的,內容都是本人經過理解加上所學內容陳述的,有些點爲了標準,也會採用作者的原話,頭條還是一個大家閒於時間打發的地方,小瘋子希望成爲一雙監督的眼鏡,給大家帶來一點實質的好書,有時間的當然可以全本閱讀,比小瘋子寫的更詳細,內容更復雜一點,我是把一些初學者沒必要深入的點簡化了,這樣學起來更流暢,後面還會有好書推薦吧,希望大家喜歡,有需要原本的可以留郵箱,作者也會每天堅持的,從六月以來面試了好幾家大公司了,偶爾也會有一點面經,http://blog.csdn.net/u011958281這是作者的博客,上面會有更多項目經驗交流跟源代碼,如果喜歡的可以去看看,缺的可以留言,樂於分享,主要是在這裏有很多志趣相投的夥伴可以交流,做起事情來也越加覺得有勁,希望大家互相鼓勵把!

HotSpot虛擬機的算法實現——深入理解Java虛擬機(八)

正文

1.枚舉根節點

主要談論之前提到GC Roots如果通着這種方式尋找到所有存活於死亡的對象,常見的叫法是可達性分析法,但是因爲現在應用越來越大,要逐個檢查定位這些引用,耗費的時間也會相對延長。

同時,可達性分析在執行時,是需要將其他程序停掉的,因爲這項分析工作必須在一個能確保一致性的快照中進行——這裏“一致性”的意思是指在整個分析期間整個執行系統看起來就像被凍結在某個時間點上,不可以出現分析過程中對象引用關係還在不斷變化的情況,該點不滿足的話分析結果準確性就無法得到保證。 這點是導致GC進行時必須停頓所有Java執行線程(Sun將這件事情稱爲“Stop The World”)的其中一個重要原因,即使是在號稱(幾乎)不會發生停頓的CMS收集器中,枚舉根節點時也是必須要停頓的。

目前的主流Java虛擬機使用的都是準確式GC,所以當執行系統停頓下來後,並不需要一個不漏地檢查完所有執行上下文和全局的引用位置,虛擬機應當是有辦法直接得知哪些地方存放着對象引用。 在HotSpot的實現中,是使用一組稱爲OopMap的數據結構來達到這個目的的,在類加載完成的時候,HotSpot就把對象內什麼偏移量上是什麼類型的數據計算出來,在JIT編譯過程中,也會在特定的位置記錄下棧和寄存器中哪些位置是引用。 這樣,GC在掃描時就可以直接得知這些信息了。

2. 安全點

額外存放對象引用OopMap是需要分配內存的,隨着對象的引用關係不斷複雜,內存也變得越來越大,這樣的OopMap對於GC來說,提高的效率就不明顯了。所以,並不是每條指令都生成了OopMap,只是在“特定的位置”記錄了這些信息,這些位置稱爲安全點(Safepoint),即程序執行時並非在所有地方都能停頓下來開始GC,只有在到達安全點時才能暫停。 Safepoint的選定既不能太少以致於讓GC等待時間太長,也不能過於頻繁以致於過分增大運行時的負荷。

另一個需要考慮的問題是如何在GC發生時讓所有線程(這裏不包括執行JNI調用的線程)都“跑”到最近的安全點上再停頓下來。 這裏有兩種方案可供選擇:搶先式中斷(Preemptive Suspension)和主動式中斷(Voluntary Suspension),其中搶先式中斷不需要線程的執行代碼主動去配合,在GC發生時,首先把所有線程全部中斷,如果發現有線程中斷的地方不在安全點上,就恢復線程,讓它“跑”到安全點上。 現在幾乎沒有虛擬機實現採用搶先式中斷來暫停線程從而響應GC事件。

主動式中斷的思想是當GC需要中斷線程的時候,不直接對線程操作,僅僅簡單地設置一個標誌,各個線程執行時主動去輪詢這個標誌,發現中斷標誌爲真時就自己中斷掛起。

3.安全區域

安全區域是擴展了的安全點,也就是整塊區域都是安全的,可以執行GC,爲什麼要這麼做,主要是考慮到執行的程序在不太長的時間就會遇到安全點,進入GC,但是程序不執行是呢,比如遇到sleep,block狀態,它就無法響應JVN中斷。

安全區域是指在一段代碼片段之中,引用關係不會發生變化。 在這個區域中的任意地方開始GC都是安全的。

在線程執行到Safe Region中的代碼時,首先標識自己已經進入了Safe Region,那樣,當在這段時間裏JVM要發起GC時,就不用管標識自己爲Safe Region狀態的線程了。 在線程要離開Safe Region時,它要檢查系統是否已經完成了根節點枚舉(或者是整個GC過程),如果完成了,那線程就繼續執行,否則它就必須等待直到收到可以安全離開Safe Region的信號爲止。

這節內容相對枯燥,我也是看了好久,主要涉及的知識比較深,也是我們在其他書看不到的,小瘋子拿來也是希望大家看後有一個概念,如果面試提起,或者你記住了,可以給自己加分的。

下一節談幾種垃圾收集器,Java語言發展這麼久也歷經了好幾代收集器的演化了。

發佈了65 篇原創文章 · 獲贊 132 · 訪問量 29萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章