2013-10-05 35 views
18

當垃圾收集器在清理未引用的對象之前凍結應用程序線程時,所有線程都必須處於執行的「安全點」。我發現了大量描述安全點概念的文字,但很少有例子。在哪裏將安全點置於典型的Java方法中,爲什麼?更重要的是,哪裏可以保證不會發生?Java GC safepoint

+1

儘管如此,拋開了本地調用,我無法找到什麼是安全點,什麼不是的例子。也許它定義不明確,但令人沮喪。 – Cowboy

+0

檢查相關示例和錯誤報告[此處](http://stackoverflow.com/q/35154352/230513)。 – trashgod

回答

6

不幸的是,這是一個不好定義的字段。 JVM在決定時放置安全點,但沒有規定何時。 Java的下一個版本/更新可能會有所不同。有一些像Unsafe.copyMemory()這樣沒有安全點的情況,但是你不能確定安全點將被放置在哪裏。

+1

嗯,但這是一個本地調用,我始終認爲本地調用是一個安全點...即可以安全地進入本機並停留在那裏,但不能回到Java代碼中(如果GC正在進行)。 – Cowboy

+1

@Cowboy正確,但copyMemory可以是任意長度,所以您複製的時間越長,達到安全點之前的時間越長。 –

+1

@PeterLawrey不安全可以有無限的長度;這就是爲什麼Bits一次只能複製1MB;這是爲了允許或保證AFAIK – bond

10

safepoint的確切定義和實現從一個虛擬機實現變爲另一個虛擬機實現,但考慮到Hotspot虛擬機,您可以在以下位置找到一個很好的定義:Safepoints in HotSpot JVM

HotSpot glossary說:

程序執行過程中的點處的所有GC根是已知的並且所有的堆對象內容是一致的。從全局角度來看,所有線程必須在GC運行之前在一個安全點處進行阻塞。

通常情況下,還原點是由JVM注入還原點檢查到的方法來實現,大多數呼叫網站有資格作爲safepoints - 到達還原點檢查時,如果需要的還原點線程將檢查(如FullGC定)如果是,則線程阻塞。當VM塊中的所有線程都已達到虛擬機中所有對象完全可達的安全點時。然後,執行請求安全點的VM操作(例如FullGC),之後線程被恢復。

檢查需要安全點的虛擬機操作列表:Safety First: Safepoints

您可以使用-XX:+PrintSafepointStatistics –XX:PrintSafepointStatisticsCount=1在Hotspot中學習安全點行爲。