safe-point(safepoint 安全點) 和 safe-region(安全區域)

以 GC safe-point引入

GC如何找到不可用的對象

編寫代碼的時候是可以知道對象不可用的,但對於程序來說,需要一定的方式來知曉,可用方法比如:編譯分析,引用計數,和對象是否可達

可達性分析

一個對象只要能夠通過mutator觸達,那麼它就是“活”着的。如果Mutator棧的一個槽位包含了對象的引用,那麼對象就是直接可觸達。而從直接可達對象可觸達的對象必定也是可達的,因而可達性分析,只需要找到直接可達的引用。

直接可達的引用就是根引用,根引用的集合就是根的集合

mutator的上下文就包含了直接可達的數據,所以要獲取對象根集合就是要找到mutator上下文中的對象引用,而mutator的上下文指的就是它的棧、它的寄存器文件以及一些線程上特定的數據

全局數據本身也是直接可達的

可達性分析爲了確保能正確的決定對象是否存活,GC需要獲取mutator 上下文的一致性快照,然後枚舉所有的根對象。

這裏的一致性指的是 快照的抽取就像只在一個時間點發生,來避免丟失一些活着的對象

如何獲取 mutator上下文的一致性快照

一種簡單的方式就是在跟引用的過程中暫停所有的線程。當mutator暫停了它的執行時,只有將所有引用信息保存在其上下文中,才能枚舉根的集合,這意味着,mutator需要能夠告知那些棧的槽位有一用,那些寄存器持有引用。如果GC能夠準確的獲取上述引用信息,它就稱作精準根集合枚舉。

無法獲取就是不精準的,以下只講精準的

如何獲取精準的引用信息枚舉

對於java來說,JIT知曉所有的棧幀信息和寄存器的內容,當JIT編譯一個方法時,對於每條指令,它都可以去保存根引用信息,保存意味着額外的存儲空間,如果要存儲所有的指令就顯得花銷太大,另外在真實的運行過程中也只有少數指令纔會成爲暫停點,因此JIT只需要保存這些指令點的信息就夠了。而真正有機會成爲暫停點的地方就稱作 safe-points,即能夠安全的枚舉根集合的暫停點

safe-point 定義

“A point in program where the state of execution is known by the VM”,即代碼中VM能夠準確知道執行狀態的位置。
safe-point有多個種類

  • GC safepoint,要觸發一次GC,JVM中的所有線程都必須達到GC safepoint
  • Deoptimization safepoint,要觸發一次 deoptimization,需要執行deoptimization的線程要到達safepoint之後纔可以開始deoptimize
Hotspot中兩者實現在一起,概念上沒有直接聯繫,需要數據不一樣

如何保證mutator會在 safe-point暫停

當GC想要觸發一次回收時,它會設置一個標誌,mutator則週期性的去檢查(poll)這個標誌,如果檢查到了,就會立馬暫停,這裏的檢查點(poll points)也是安全點,由JIT負責把poll points放到合適的位置

那些地方適合設置檢查GC事件的標記

polling point插入的主要原則是:

  1. polling point應該足夠多,防止GC等一個mutator的暫停太長,導致其他mutator都走在等GC釋放空間,程序整個等待過長
  2. polling point不能太頻繁導致運行時存儲開銷過大
  3. polling本身也是有開銷的,不能過多

權衡下來只在必須和必要的地方加

  1. 在分配地址的時候強制添加,因爲分配空間很有肯能導致回收,所以這裏是一個安全點
  2. 長時間的執行一般意味着循環和方法調用,所以方法調用和循環返回最好加上

但是有時候並不是長時間的執行,而是長時間的空閒,比如 sleep、block,線程在執行其他的native函數,這些時候JVM無法掌控執行能力,也就無法響應GC事件。

不同的JVM選用不同的位置放置safepoint。

如何解決sleep/block 帶來的問題

引用safe-region。safe-region是指代碼快中沒有用到會變異的部分,這樣的代碼塊中,任何一個點都可以安全的枚舉根。當進入到safe-region中時,mutator會設置一個準備標記,在離開safe-region區域之前,會檢查GC是否已經完成了回收,如果沒有,那麼就暫停執行,如果有,就可以直接離開safe-region區域,不需要暫停mutator

文章翻譯自 Xiao-Feng Li 博客

rednaxelafx對safepoint的回答

總結

代碼的執行過程中,如果需要執行某些操作,比如GC,deoptimize,等等,必須知道當前程序所有線程運行到的地方,是否能夠恰好滿足我執行對應操作,而不會對應用程序本身造成損害,這些能夠正確執行操作的地方也就是safepoint/saferegion

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