【问题标题】:JNI local ref lifetime in a JVM host appJVM 主机应用程序中的 JNI 本地引用生命周期
【发布时间】:2016-10-28 16:44:26
【问题描述】:

JNI 文档声明本地 Java 对象引用在本地方法返回之前都在范围内;而且它们是线程本地的。

当应用程序托管 Java VM 时,Java 对象引用可能会在任何本机方法之外创建。一旦 JVM 运行,宿主应用程序可能会获得一个JNIEnv 并创建它想要的所有 Java 对象。假设这种情况会产生本地参考。

请问这些人的寿命是多少?它们是否与 JVM 一样长(除非明确释放)?他们也是本地线程吗?如果在工作线程上,一旦线程与 JVM 分离,它们是否会超出范围?

特别是关于线程局部性:到目前为止,在线程之间重用类对象(从FindClass() 返回)对我来说可以正常工作。但这是否违反了 JNI 规则?

【问题讨论】:

  • 无需假设。 JNI 规范说“JNI 函数返回的所有 Java 对象都是本地引用”。它还说您不能将本地引用从一个本机线程传递到另一个本机线程。鉴于这两种说法,您的困难是什么尚不清楚。
  • 在类对象方面我为什么总是逍遥法外?
  • @SevaAlekseyev 幸运的机会。例如。作为长寿命对象的类实例往往会落到它们很少移动的老年代。但是,这绝对不能保证。一旦 Class 实例在 Heap 中重定位,访问无效的 jclass 本地引用可能会导致 JVM 崩溃。
  • 因为你很幸运。你不能依赖运气。您可以依赖规范。

标签: java jvm java-native-interface


【解决方案1】:

可通过以下方式获得可用于创建本地引用的有效JNIEnv

  1. 本机方法调用。本地引用在方法返回之前一直有效。
  2. JVMTI 回调。同样,本地引用将一直存在,直到回调返回。
  3. GetEnv 来电。

    3.1。来自JNI_OnLoadAgent_OnLoadAgent_OnAttach 条目。在这些条目中创建的本地引用在从条目返回之前一直有效。

    3.2。来自AttachCurrentThread 函数附加的线程。引用将一直有效,直到调用 DetachCurrentThread

所有本地引用都是在其中创建它们的only valid in the thread。本机代码不得将本地引用从一个线程传递到另一个线程。

请注意,JVM 保证1,2 可以在一帧中创建 16 个本地引用。如果您需要更多本地引用,则必须使用 PushLocalFrame / PopLocalFrame JNI 函数显式管理它们。

jclassjthreadjstringjarray等都是JNI references,如jobject。它们也需要进行管理,这与不是 JNI 引用的 jmethodIDjfieldID 不同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 2011-03-03
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-02
    相关资源
    最近更新 更多