譯文 GC 安全點 和安全區域

2022-02-02 10:38:31 字數 2719 閱讀 2684

根引用  root references

乙個例項死了,意味著它變得無用。只用程式設計師知道乙個例項是否已經無用。為了讓程式知道乙個例項是否已經無用,我們可以使用編譯器分析,引用計數, 或者 可達性分析。

可達性分析假設只要乙個例項是可達的,它就是活著的。如果乙個例項的引用直接包含在當前函式棧的乙個槽(slot)中,它就是直接可達的。那些被可達例項引用的例項也是可達的。因此,可達性分析就是找出那些直接可達的引用,也就是根引用。 根引用的集合就做根集合。

當前執行函式(the mutator)的上下文中 有直接可達的資料,因此 找根集合就是在上下文中找例項的引用。當前函式的上下文引用它的棧和暫存器檔案(和一些執行緒所有的資料)。全域性資料也是直接可達的。

列舉根集合root set enumeration

一般情況下,如果gc使用可達性來確定乙個例項是否存活,gc需要獲得當前執行現場的乙個一致的快照(a consistent snapshot),以便列舉根引用。 這對於stop-the-world 和 併發 gc(多數情況)都適用。 「一致」 意味著快照看起來就像在單個時間點上取得的。 乙個一致的根引用快照對於正確性很有必要,否則一些活著的例項就可能丟失。 那現在的問題就是怎樣獲得當前上下文一致的快照。

為了獲得一致的快照,乙個簡單的辦法就是在列舉根引用的過程中,當前執行函式阻塞。 如果在列舉過程中,根集合是不變的,快照也是一致的。

當前執行函式阻塞了它的執行以後,它就不一定能夠列舉它上下文中的根引用,除非它在它的上下文中登記並儲存了那些引用資訊。也就是說,它應該能夠分辨出那個棧裡有引用,哪個暫存器裡有引用。 如果gc能夠準確地獲得這些資訊,它就是準確根集合列舉, 否則就是模糊的。

(對應模糊列舉,gc使用啟發式規則來保守地猜測哪些是上下文中的引用。因此,這些gc就是所謂的保守gc。 這篇文章只討論準確列舉。)

harmony 通過使用gc安全點和安全區域, 支援準確根集合列舉。

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

為了支援準確列舉,jit編譯器需要做一些額外的工作,因為只有jit準確地知道棧幀資訊和暫存器上下文。 當jit編譯乙個方法的時候, 對於每乙個指令, 它都儲存根引用資訊,以防執行阻塞在那個指令上。

但是對每乙個指令都儲存那些資訊太昂貴了。 它需要大量空間儲存那些資訊。 這是不必要的,因為 只有一小部分指令有機會在實際執行時阻塞。 jit只需要儲存那部分指令的資訊就夠了-- 他們就把叫做安全點。安全點意味著對應根列舉來說,在該點阻塞是安全的。

順便說一下,並不是所有程式語言的編譯器都能夠確切知道堆疊資訊。 只有安全語言有這個能力。 比如, c/c++就沒有。

函式阻塞 mutator suspension

對於安全點,現在的問題是,我們怎麼保證函式在安全點阻塞。

有兩種基本方法來阻塞當前函式,搶先或者自願。搶先式的方法是無論任何時候gc需要進行一次收集,它都立即阻塞當前函式的執行。當它發現函式被阻塞在乙個不安全的點時,它會恢復函式執行,向前滾動到乙個安全點。這種方法在orp中實現,它是harmony的前乙個版本。但是,目前幾乎沒有jvm使用這種方法。

在harmony中實現的方法是自願阻塞。當gc觸發一次垃圾**,它只是簡單的設定乙個標誌; 當前執行函式會輪詢這個標誌, 當發現這個標誌置位的時候,他們就會阻塞。那些輪詢的點都是安全點。 多數情況下, jit負責在合適的位置插入輪詢程式。 有時,vm也需要有一些輪詢點。

輪詢點 polling point

那麼**是正確輪詢gc觸發事件的地點呢? 就像我們上面討論的,我們不想在每乙個指令處都設定輪詢點。 對於自願阻塞,乙個更嚴重的問題是輪詢負載。因此插入輪詢點需要遵循一些基本原則:第一,輪詢點應該足夠頻繁,以便gc不需要等待當前函式阻塞的時間太長, 因為其他函式還在等著gc釋放空間來繼續執行。第二,輪詢點不能太多,導致增加執行負載過重。

最好的結果是剛好有足夠的輪詢點滿足需求:

一類強制的輪詢點是記憶體分配點。分配可以觸發一次垃圾收集,因此分配必須是安全點

長時間的執行總是和方法呼叫或者迴圈 有關。因此,呼叫點和迴圈回邊點也是期望的輪詢點  

這些就是harmony中的輪詢點: 分配點,呼叫點和迴圈回邊點。 多數情況下執行時負載小於1%。 不幸的是,我們發現單獨安全點是不夠的。

安全區域 safe-region

為什麼不夠呢? 因為我們忘掉了一種常見執行的情況。我們忘了它,因為它實際上不是長時間執行,而是長時間閒置。有這樣一類情況程式不能及時響應gc觸發事件,比如sleep,因系統呼叫阻塞。 這些操作不是jvm能夠控制的。jvm在此期間不能夠響應gc事件。 因此,我們引入了安全區域的概念來解決這個問題。

安全區域是其中引用不會改變的一段**片段,那麼在其中任一點進行根列舉都是安全的。 換句話說,安全區域是安全點的乙個很大的擴充套件。

在安全點的設計中,如果gc觸發事件發生了,執行函式通過輪詢進行響應。它通過設定乙個準備好的標誌(ready flag)來響應。 那麼gc就可以進行根列舉了。這是乙個握手協議。

安全區域也遵循這個協議。執行函式在進入安全區域時設定ready flag。在它離開安全區域以前,它先檢查gc是否完成了列舉(或者收集),並且不再需要執行函式呆在阻塞狀態。如果是真的,它就向前執行,離開安全區域; 否則,它就像安全點一樣阻塞他自己。

在harmony的實現中,我們插入 suspend_enable 和 suspend_disable來標誌安全區域的界限。

orp (open runtime platform), ;

iOS iphonex底部安全區域

問題出在哪,不是你的iphone x是假的,是真的獲取不到。只有在vc的 void viewdidlayoutsubviews這個方法裡,你獲取到的才是,所以在這方法裡面才能獲取到self.view.safeareainsets.bottom的值。為什麼會出現這種情況,下面說明vc中的兩個方法 1....

談談Jvm的安全點與安全區域

安全點與安全區域 安全點就是指 中一些特定的位置,當執行緒執行到這些位置時它的狀態是確定的,這樣jvm就可以安全的進行一些操作,比 如gc等,所以gc不是想什麼時候做就立即觸發的,是需要等待所有執行緒執行到安全點後才能觸發。這些特定的安全點位置主要有以下幾種 1.方法返回之前 2.呼叫某個方法之後 ...

安全區域邊界 (五)安全審計

安全區域邊界 控制點 5.安全審計 安全審計是指針對等級保護物件中與安全活動相關的資訊進行識別 記錄 儲存和分析的整個過程。安全審計功能可確保使用者對其行為負責,證實安全政策得以實施,並可用作調查工具。通過檢查審計記錄結果可以判斷發生了哪些安全相關活動以及哪個使用者要對這些活動負責。另外安全審計可協...