【问题标题】:JNI code ie executed concurrently with garbage collection.JNI 代码即与垃圾收集同时执行。
【发布时间】:2018-07-13 09:20:58
【问题描述】:

写在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.                     |

JVM 是如何处理的?

【问题讨论】:

  • 本机代码中的jobjects 是间接引用。实际的间接机制可能在不同的 JVM 之间有所不同,使用压缩 GC 的 JVM 必须实现允许移动对象的间接机制。
  • 不清楚你在问什么。没有人说你不能在 JNI 中执行 setter,也没有人说 jobject 参数在 JNI 调用期间不能移动到另一代,具体来说,没有人说 jobject 直接指向 在内存中的 Java 对象处,
  • 当您使用JVM方法访问对象时,即使您正在运行GC,它也确保它仍然是安全的。如果您有 STW 集合,这很可能会立即停止 JNI 中的线程。

标签: garbage-collection jvm java-native-interface


【解决方案1】:

几乎每个 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 完成。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多