Java JVM主机应用程序中的JNI本地引用生存期

Java JVM主机应用程序中的JNI本地引用生存期,java,jvm,java-native-interface,Java,Jvm,Java Native Interface,JNI文档声明本地Java对象引用在本地方法返回之前都在作用域中;而且它们是线程的本地 当应用程序托管Java VM时,Java对象引用可能会在任何本机方法之外创建。JVM运行后,主机应用程序可能会获得JNIEnv,并创建它想要的Java对象。我们假设此场景会生成局部引用 请问这些东西的寿命是多少?它们的寿命是否与JVM的寿命一样长(除非显式释放)?他们也是本地人吗?如果在工作线程上,那么一旦线程与JVM分离,它们是否会超出范围 特别是关于线程位置:到目前为止,在线程之间重用类对象(从FindC

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

当应用程序托管Java VM时,Java对象引用可能会在任何本机方法之外创建。JVM运行后,主机应用程序可能会获得
JNIEnv
,并创建它想要的Java对象。我们假设此场景会生成局部引用

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


特别是关于线程位置:到目前为止,在线程之间重用类对象(从
FindClass()
返回)对我来说是可以预期的。但这是否违反了JNI规则?

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

  • 本机方法调用。在方法返回之前,本地引用将一直有效
  • JVMTI回调。类似地,本地引用将一直存在,直到回调返回
  • 打电话

    3.1。从
    JNI_OnLoad
    Agent_OnLoad
    Agent_OnAttach
    条目。在这些条目中创建的本地引用在该条目返回之前是有效的

    3.2。从函数附加的线程。在调用之前,引用将处于活动状态

  • 所有本地引用都是在其中创建它们的。本机代码不能将本地引用从一个线程传递到另一个线程

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


    jclass
    jthread
    jstring
    jarray
    等都类似于
    jobject
    。它们也需要管理,这与不是JNI引用的
    jmethodID
    jfieldID
    不同。

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

  • 本机方法调用。在方法返回之前,本地引用将一直有效
  • JVMTI回调。类似地,本地引用将一直存在,直到回调返回
  • 打电话

    3.1。从
    JNI_OnLoad
    Agent_OnLoad
    Agent_OnAttach
    条目。在这些条目中创建的本地引用在该条目返回之前是有效的

    3.2。从函数附加的线程。在调用之前,引用将处于活动状态

  • 所有本地引用都是在其中创建它们的。本机代码不能将本地引用从一个线程传递到另一个线程

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


    jclass
    jthread
    jstring
    jarray
    等都类似于
    jobject
    。它们也需要管理,不像
    jmethodID
    jfieldID
    不是JNI引用。

    不需要假设。JNI规范说“JNI函数返回的所有Java对象都是本地引用。”它还说您不能将本地引用从一个本机线程传递到另一个本机线程。考虑到这两种说法,不清楚您的困难是什么。在类对象方面,我为什么总是能侥幸逃脱呢?@SevaAlekseyev,这是一个幸运的机会。例如,作为长寿命对象的类实例往往属于旧一代,它们很少移动。然而,这是绝对不能保证的。一旦类实例在堆中重新定位,对无效的
    jclass
    本地引用的访问可能会导致JVM崩溃。你不能靠运气。您可以依赖规范,无需假设。JNI规范说“JNI函数返回的所有Java对象都是本地引用。”它还说您不能将本地引用从一个本机线程传递到另一个本机线程。考虑到这两种说法,不清楚您的困难是什么。在类对象方面,我为什么总是能侥幸逃脱呢?@SevaAlekseyev,这是一个幸运的机会。例如,作为长寿命对象的类实例往往属于旧一代,它们很少移动。然而,这是绝对不能保证的。一旦类实例在堆中重新定位,对无效的
    jclass
    本地引用的访问可能会导致JVM崩溃。你不能靠运气。你可以信赖说明书。