26

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

4

2 回答 2

17

从一个 VM 实现到另一个的更改的确切定义和实现safepoint,但考虑到 Hotspot VM,您可以在:HotSpot JVM中的安全点中找到一个很好的定义。

热点词汇表说:

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

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

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

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

于 2013-10-05T19:20:54.793 回答
9

不幸的是,这是一个定义不佳的领域。JVM 在决定时放置安全点,但没有具体说明何时。Java 的下一个版本/更新可能会有所不同。在某些情况下,例如 Unsafe.copyMemory() 没有安全点,但您无法确定安全点的放置位置。

于 2013-10-05T18:45:37.407 回答