在 jvm 中如何判斷物件可以被** 一文中,我們知道 hotspot 虛擬機器採取的是可達性分析演算法。即通過 gc roots 列舉判定待**的物件。
那麼,首先要找到哪些是 gc roots。
有兩種查詢 gc roots 的方法:
一種是遍歷方法區和棧區查詢(保守式 gc)。
一種是通過 oopmap 資料結構來記錄 gc roots 的位置(準確式 gc)。
很明顯,保守式 gc 的成本太高。準確式 gc 的優點就是能夠讓虛擬機器快速定位到 gc roots。
對應 oopmap 的位置即可作為乙個安全點(safe point)。
在執行 gc 操作時,所有的工作執行緒必須停頓,這就是所謂的」stop-the-world」。
為什麼呢?
因為可達性分析演算法必須是在乙個確保一致性的記憶體快照中進行。如果在分析的過程中物件引用關係還在不斷變化,分析結果的準確性就不能保證。
安全點意味著在這個點時,所有工作執行緒的狀態是確定的,jvm 就可以安全地執行 gc 。
安全點太多,gc 過於頻繁,增大執行時負荷;安全點太少,gc 等待時間太長。
一般會在如下幾個位置選擇安全點:
1、迴圈的末尾
2、方法臨返回前
3、呼叫方法之後
4、拋異常的位置
主要的目的就是避免程式長時間無法進入 safe point。比如 jvm 在做 gc 之前要等所有的應用執行緒進入安全點,如果有乙個執行緒一直沒有進入安全點,就會導致 gc 時 jvm 停頓時間延長。比如這裡,超大的迴圈導致執行 gc 等待時間過長。
主要有兩種方式:
搶斷式中斷:在 gc 發生時,首先中斷所有執行緒,如果發現執行緒未執行到 safe point,就恢復執行緒讓其執行到 safe point 上。
主動式中斷:在 gc 發生時,不直接操作執行緒中斷,而是簡單地設定乙個標誌,讓各個執行緒執行時主動輪詢這個標誌,發現中斷標誌為真時就自己中斷掛起。
jvm 採取的就是主動式中斷。輪詢標誌的地方和安全點是重合的。
safe point 是對正在執行的執行緒設定的。
如果乙個執行緒處於 sleep 或中斷狀態,它就不能響應 jvm 的中斷請求,再執行到 safe point 上。
因此 jvm 引入了 safe region。
safe region 是指在一段**片段中,引用關係不會發生變化。在這個區域內的任意地方開始 gc 都是安全的。
執行緒在進入 safe region 的時候先標記自己已進入了 safe region,等到被喚醒時準備離開 safe region 時,先檢查能否離開,如果 gc 完成了,那麼執行緒可以離開,否則它必須等待直到收到安全離開的訊號為止。
JVM 安全點介紹
在 jvm 中如何判斷物件可以被 一文中,我們知道 hotspot 虛擬機器採取的是可達性分析演算法。即通過 gc roots 列舉判定待 的物件。那麼,首先要找到哪些是 gc roots。有兩種查詢 gc roots 的方法 一種是遍歷方法區和棧區查詢 保守式 gc 一種是通過 oopmap 資料...
談談Jvm的安全點與安全區域
安全點與安全區域 安全點就是指 中一些特定的位置,當執行緒執行到這些位置時它的狀態是確定的,這樣jvm就可以安全的進行一些操作,比 如gc等,所以gc不是想什麼時候做就立即觸發的,是需要等待所有執行緒執行到安全點後才能觸發。這些特定的安全點位置主要有以下幾種 1.方法返回之前 2.呼叫某個方法之後 ...
JVM執行緒安全與鎖優化
1.不可變 不可變的物件一定是執行緒安全的。如string類。2.絕對執行緒安全 3.相對執行緒安全 4.執行緒相容 5.執行緒對立 1.互斥同步 阻塞式同步 1 同步指的是 多個執行緒併發訪問共享資料時,保證共享資料在同一時刻只能被乙個執行緒使用。2 互斥指的是 同步的手段。如 臨界區 互斥量和訊...