日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HotSpot 虚拟机垃圾回收算法实现

發(fā)布時間:2023/11/30 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HotSpot 虚拟机垃圾回收算法实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

作為使用范圍最廣的虛擬機之一HotSpot,必須對垃圾回收算法的執(zhí)行效率有嚴格的考量,只有這樣才能保證虛擬機高效運行

枚舉根節(jié)點

從可達性分析中從 GC Roots 節(jié)點找引用鏈這個操作為例,可以作為 GC Roots 的節(jié)點主要在全局性的引用(例如常量或者類靜態(tài)屬性)與執(zhí)行上下文(例如棧幀中的本地變量表)中。

但是現(xiàn)在很多應用僅僅方法區(qū)就有數(shù)百兆,如果要逐個檢查這里面的引用,那么必然會消耗很多的時間。

另外,可達性分析對執(zhí)行時間的敏感還體現(xiàn)在 GC 停頓上,因為這項分析工作必須在一個能確保一致性的快照中進行 —— 這里的“一致性”指的是在整個分析過程中整個執(zhí)行系統(tǒng)看起來就像是被凍結(jié)在某個時間點上,不可以出現(xiàn)分析過程中對象引用關(guān)系還在不停變化的情況,該點不滿足的話分析結(jié)果準確性就無法得到保證。

這點是導致 GC 進行時必須停頓所有 Java 執(zhí)行線程的其中一個重要原因,即使是號稱不會發(fā)生停頓的 CMS 收集器中,枚舉根節(jié)點也是必須要停頓的。

由于目前主流 Java 虛擬機使用的都是準確式 GC,所以當執(zhí)行系統(tǒng)停頓下來后,并不需要一個不漏的檢查完成所有執(zhí)行上下文和全局的引用位置,虛擬機應當是有辦法直接得知那些地方存放著對象引用的。 在HotSpot的實現(xiàn)中,是使用一組被稱為OopMap的數(shù)據(jù)結(jié)構(gòu)來達到這個目的的,在類加載的時候,HotSpot就把對象內(nèi)什么偏移量上是什么類型的數(shù)據(jù)計算出來,在JIT 編譯過程中,也會在特定的位置記錄下棧和寄存器中哪些位置是引用。這樣, GC 在掃描時就可以直接得知這些信息了。

安全點

在 OopMap 的幫助下,HotSpot 可以快速并且準確的完成 GC Roots 枚舉,但是一個很現(xiàn)實的問題隨之而來:可能導致引用關(guān)系變化,或者說 OopMap 內(nèi)容變化的指令非常多,如果為每一條指令都生成對應的 OopMap,那么將需要大量的額外空間,這樣 GC 的空間成本將會變得很高。

實際上,HotSpot 也的確沒有為每一條指令都生成 OopMap,只是在“特定的位置” 記錄了這些信息,這些位置被稱為是安全點,即程序執(zhí)行時并非是在所有地方都能停頓下來開始 GC ,只有到達安全點時才能暫停。

安全點的選擇既不能太少以至于讓 GC 等待太長時間,也不能過于頻繁以至于過分增大運行時負荷。

所以,安全點的選定基本上是以程序“是否具有讓程序長時間執(zhí)行的特征”為標準進行選定的——因為每條指令執(zhí)行的時間都非常短暫,程序不太可能因為指令流長度太長這個原因而過長時間運行,“長時間執(zhí)行”的最明顯特征就是指令序列復用,例如方法調(diào)用、循環(huán)跳轉(zhuǎn)、異常跳轉(zhuǎn)等,所以具有這些功能的指令才會產(chǎn)生安全點。

對于安全點,另一個需要考慮的問題就是如何讓 GC 發(fā)生時讓所有線程(這里不包括執(zhí)行 JNI 調(diào)用的線程)都“跑”到最近的安全點再停頓下來。這里有兩種方案可供選擇:搶先式中斷和主動式中斷。

  • 搶先式中斷:無需線程的執(zhí)行代碼主動配合,在 GC 發(fā)生時,首先把所有線程全部中斷,如果發(fā)現(xiàn)有線程中斷的地方不再安全點上,就會發(fā)線程,讓它“跑”到安全點上。現(xiàn)在幾乎沒有虛擬機實現(xiàn)采用搶先式中斷來暫停線程從而響應GC事件
  • 主動式中斷:當 GC 需要中斷線程時,不直接對線程操作,僅僅簡單地設(shè)置一個標志,各個線程執(zhí)行時主動去輪詢這個標志,發(fā)現(xiàn)中斷標志為真時就自己中斷掛起。輪詢標志的地方和安全點是重合的,另外再加上創(chuàng)建對象需要分配內(nèi)存的地方。

安全區(qū)域

使用安全點似乎已經(jīng)完美解決了如何進入 GC 的問題,但實際情況卻并不一定,安全點機制保證了程序執(zhí)行,在不太長的時間內(nèi)就會遇到可以進入 GC 的安全點。

但是線程“不執(zhí)行”的時候呢?所謂不執(zhí)行就是沒有分配 CPU 時間,典型的例子就是線程處于 Sleep 狀態(tài)或者 Blocked狀態(tài),這時候線程無法響應 JVM 的中斷請求,“走”到安全點去中斷掛起,JVM顯然也不太可能等待線程重新被分配 CPU 時間。對于這種狀況,就需要安全區(qū)域來解決。

安全區(qū)域就是在一段代碼片段中,引用關(guān)系不會發(fā)生變化,在這個區(qū)域中的任意地方開始 GC 都是安全的。

在線程執(zhí)行到安全區(qū)域中的代碼時,首先標識自己已經(jīng)進入了安全區(qū)域,那樣,當這段時間里 JVM 要發(fā)起 GC 時,就不用管標識自己為安全區(qū)域狀態(tài)的線程了。

當線程要離開安全區(qū)域時,它要檢查系統(tǒng)是否已經(jīng)完成了根節(jié)點枚舉(或者是整個 GC 過程),如果完成了,那線程就繼續(xù)執(zhí)行,否則它就必須等待直到收到可以安全離開安全區(qū)域的信號為止。

轉(zhuǎn)載于:https://www.cnblogs.com/AmosH/p/10346924.html

總結(jié)

以上是生活随笔為你收集整理的HotSpot 虚拟机垃圾回收算法实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。