Java GC安全点

Java GC安全点,java,garbage-collection,Java,Garbage Collection,当垃圾收集器在清理未引用的对象之前冻结应用程序线程时,所有线程在执行时都必须处于“安全点”。我找到了大量描述安全点概念的文章,但很少有例子。在一个典型的Java方法中,safepoint放在哪里?为什么?更重要的是,哪里可以不出现安全点?不幸的是,这是一个定义不好的字段。JVM决定何时放置安全点,但没有关于何时放置的规范。Java的一个版本/更新到下一个版本可能会有所不同。有些情况下,例如Unsafe.copyMemory()没有safepoint,但您无法确定safepoints将放置在何处。

当垃圾收集器在清理未引用的对象之前冻结应用程序线程时,所有线程在执行时都必须处于“安全点”。我找到了大量描述安全点概念的文章,但很少有例子。在一个典型的Java方法中,safepoint放在哪里?为什么?更重要的是,哪里可以不出现安全点?

不幸的是,这是一个定义不好的字段。JVM决定何时放置安全点,但没有关于何时放置的规范。Java的一个版本/更新到下一个版本可能会有所不同。有些情况下,例如Unsafe.copyMemory()没有safepoint,但您无法确定safepoints将放置在何处。

safepoint的确切定义和实现会从一个VM实现更改为另一个VM实现,但考虑到Hotspot VM,您可以在中找到一个很好的定义:

说:

程序执行过程中的一个点,在该点上所有GC根都是已知的,并且所有堆对象内容都是一致的。从全局角度来看,所有线程必须在安全点阻塞,GC才能运行

通常,safepoint是通过JVM向方法中注入safepoint检查来实现的,大多数调用站点都符合safepoints的条件-当达到safepoint检查时,线程将检查是否需要safepoint(例如,安排了FullGC),如果是,则线程阻塞。当VM中的所有线程都被阻塞时,您已经到达了安全点,VM中的所有对象都可以完全访问。然后,执行请求安全点的VM操作(例如FullGC),然后恢复线程

检查需要安全点的VM操作列表:


您可以使用
-XX:+PrintSafepointStatistics-XX:PrintSafepointStatisticsCount=1

Uhm来研究热点中的安全点行为,但这是一个本机调用,我始终认为本机调用是一个安全点。。。i、 e.可以安全地输入本机并停留在那里,但不能返回Java代码(以防GC正在进行)。@Cowboy正确,但copyMemory可以是任意长度,因此复制的时间越长,到达安全点之前的时间就越长。@PeterLawrey safe可以有无限长;这就是Bits一次最多只能复制1MB的原因;这是为了允许或安全点AFAIKStill,撇开本机调用不谈,我无法找到什么是安全点,什么不是安全点的示例。也许它的定义很差,但令人沮丧。本文将研究一个相关的示例和错误报告。