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

最佳答案

safepoint的确切定义和实现从一种VM实现更改为另一种VM实现,但是考虑到Hotspot VM,您可以在Safepoints in HotSpot JVM中找到一个不错的定义。

HotSpot glossary说:


  程序执行期间的一点,所有GC根都是已知的,并且所有堆对象的内容都一致。从全局角度来看,GC可以运行之前,所有线程都必须在安全点处阻塞。


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

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

您可以使用-XX:+PrintSafepointStatistics –XX:PrintSafepointStatisticsCount=1在Hotspot中研究安全点行为。

10-04 16:22