它写在http://psy-lob-saw.blogspot.com/2015/12/safepoints.html
上在执行JNI代码时,Java线程处于安全点。之前 越过本地调用边界,堆栈将保持一致 在移交给本机代码之前先进行状态处理。这意味着 线程仍然可以在安全点上运行。
怎么可能?毕竟,我可以将对象的引用传递给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. |
JVM如何处理?
答案 0 :(得分:4)
几乎每个JNI调用都有一个安全点保护程序。每当您从本机方法调用JNI函数时,线程就会从in_native
切换到in_vm
状态。此过渡的一部分是安全点检查。
请参见ThreadStateTransition::transition_from_native(),它会调用JavaThread::check_safepoint_and_suspend_for_native_trans(thread)
// 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.
也就是说,在GC处于活动状态时调用JNI函数的线程将被挂起,直到GC完成。