一文講清楚 JVM Safe Point


一文講清楚 JVM Safe Point

文章插圖
大家好,我是樹哥 。
關于 Safe Point 是 JVM 中很關鍵的一個概念,但我估計有不少同學不是很懂 。于是今天跟大家來深入聊聊 Safe Point , 希望通過這篇文章能解答這樣幾個問題:
  1. 什么是 Safe Point?
  2. 為啥需要 Safe Point?
  3. Safe Point 與 Stop the World 的關系?
什么是 Safe Point正如 Safe Point 名稱的寓意一樣,Safe Point 是一個線程可以安全停留在這里的代碼點 。當我們需要進行 GC 操作的時候,JVM 可以讓所有線程在 Safe Point 處停留下來,等到所有線程都停在 Safe Point 處時,就可以進行內存引用分析,從而確定哪些對象是存活的、哪些對象是不存活的 。
為什么讓大家更加場景化地理解 Safe Point 這個概念,可以設想如下場景:
  1. 當需要 GC 時,需要知道哪些對象還被使用 , 或者已經不被使用可以回收了,這樣就需要每個線程的對象使用情況 。
  2. 對于偏向鎖(Biased Lock),在高并發時想要解除偏置,需要線程狀態還有獲取鎖的線程的精確信息 。
  3. 對方法進行即時編譯優化(OSR 棧上替換),或者反優化(bailout 棧上反優化) , 這需要線程究竟運行到方法的哪里的信息 。
【一文講清楚 JVM Safe Point】對于上面這些操作,都需要知道現場的各種信息,例如寄存器有什么內容,堆使用情況等等 。在做這些操作的時候,線程需要暫停,等到這些操作完成才行,否則會有并發問題,這就需要 Safe Point 的存在 。
因此,我們可以將 Safe Point 理解成代碼執行過程中的一些特殊位置,當線程執行到這個位置時 , 線程可以暫停 。Safe Point 處保存了其他位置沒有的一些當前線程信息 , 可以提供給其他線程讀??,諒T┬畔ǎ合叱躺舷攣男畔? ,對象的內部指針等 。
而 Stop the World 就是所有線程同時進入 Safe Point 并停留在那里 , 等待 JVM 進行內存分析掃描,接著進行內存垃圾回收的時間 。
為啥需要 Safe Point前面我們說到,Safe Point 其實就是一個代碼的特殊位置 , 在這個位置時線程可以暫停下來 。而當我們進行 GC 的時候,所有線程都要進入到 Safe Point 處,才可以進行內存的分析及垃圾回收 。根據這個過程,其實我們可以看到:Safe Point 其實就是柵欄的作用,讓所有線程停下來 , 否則如果所有線程都在運行的話,JVM 無法進行對象引用的分析 , 那么也無法進行垃圾回收了 。
此外,另一個重要的 Java 線程特性 —— interrupted 也是根據 Safe Point 實現的 。當我們在代碼里寫入 Thread.interrupt() 時 , 只有線程運行到 Safe Point 處時才知道是否發生了 interrupted 。因此,Safe Point 也承擔了存儲線程通信的功能 。
總結簡單地說 , Safe Point 就是人為規定出的一些代碼位置,在這些位置上線程可以暫停下來,從而讓 JVM 可以進行內存對象引用分析等操作 。此外,Safe Point 處也會存儲一些特殊的信息,從而支持 Java 的某些特性,例如:Java 的 interrupt 特性需要到 Safe Point 處才能知道 。
其實關于 Safe Point 的內容還有不少,例如:
  1. 什么地方會放 Safe Point?
  2. Safe Point 具體是怎么實現的?
  3. 什么情況會讓所有線程進入 Safe Point?
但對于大多數應用開發人員來說,其實暫時不需要了解得這么深,只需要知道啥是 Safe Point 以及其存在的價值即可 。如果你對這些問題感興趣,可以通過參考資料部分詳細了解 。
參考資料
  • JVM 相關 - SafePoint 與 Stop The World 全解 - 知乎
  • JVM源碼分析之安全點safepoint - 簡書

    推薦閱讀