JNI 代码即与垃圾收集并发执行。

Gil*_*esz 4 java-native-interface garbage-collection jvm

它写在http://psy-lob-saw.blogspot.com/2015/12/safepoints.html

Java 线程在执行 JNI 代码时处于安全点。在越过本机调用边界之前,堆栈在移交给本机代码之前保持一致状态。这意味着线程仍然可以在安全点运行。

这怎么可能?毕竟,我可以将对象的引用传递给JNI. 在 JNI 中,我可以在该对象中设置一个字段。

很明显是收不到的(我们有本地参考)。但是,它可以在完整的 gc 收集期间通过 GC 移动到老年代。所以,我们有以下情况:

GC collector:                          | Thread executing JNI code
compact old generation                 | modify object fields that can be 
and move object from young generation  | moved now! A catastrophe. 
to old generation.                     |
Run Code Online (Sandbox Code Playgroud)

JVM 如何处理?

apa*_*gin 5

几乎每个 JNI 调用都有一个安全点保护。每当您从本机方法调用 JNI 函数时,线程就会从状态切换in_nativein_vm状态。此转换的一部分是安全点检查。

参见调用JavaThread::check_safepoint_and_suspend_for_native_trans(thread) 的ThreadStateTransition::transition_from_native( )

// Slow path when the native==>VM/Java barriers detect a safepoint is in
// progress or when _suspend_flags is non-zero.
// Current thread needs to self-suspend if there is a suspend request and/or
// block if a safepoint is in progress.
Run Code Online (Sandbox Code Playgroud)

也就是说,在 GC 处于活动状态时调用 JNI 函数的线程将被挂起,直到 GC 完成。