java - 如果调用 JNI DeleteGlobalRef(),相应的 java 对象是否会被垃圾回收?

标签 java c++ java-native-interface

我的意思是,如果我在 C++ 中创建一个全局引用 jobject,然后将其传递给一些 Java 代码,并删除调用 DeleteGlobalRef(),那么底层 Java 对象可能会立即被垃圾回收,因此任何 future 已经引用该对象的 Java 代码可能会返回 NullPointerException?具体来说,如果我有一些 C++ 代码执行类似这个简化示例的操作:

static jobject myObjGlobalRef;
static JNIEnv* env = /* call to create a JVM and get the JNI env */;
jobject ReturnMyObj()
{
    /* <<Code that defines class, constructorId, and param1 goes here>> */

    jobject localObj = env->NewObject(class, constructorId, param1);
    myObjGlobalRef = env->NewGlobalRef(localObj);
}

void DeleteMyObj()
{
    env->DeleteGlobalRef(myObjGlobalRef);
}

myObjGlobalRef = ReturnMyObj();

jobject otherExistingGlobalRef = /* Assume we get another global ref to another parent obj somewhere else */
/*  ... other code here ... */
// Invoke some method on some other pre-existing global reference that uses
// myObjGlobalRef,  lets assume this method stores the object referenced by
// myObjGlobalRef into a parent object referenced by otherExistingGlobalRef:
env->CallVoidMethod(env, otherExistingGlobalRef, addASubObjectMethodId, myObjGlobalRef);

DeleteMyObj();

// Does the pointed to by myObjGlobalRef still exist here, assuming that
// otherExistingGlobalRef now references it?

这在 JNI 中是如何工作的?对象上的“GlobalReference”只是对该对象的引用计数,因此如果我释放 GlobalReference jobject,它不一定会垃圾收集底层 java 对象,直到对它的所有引用(例如“父”对象 otherExistingGlobalRef 引用它)消失了吗?

如果您能回答这个问题并提供一些官方 Java/Sun/Oracle 文档的链接来支持您的回答,您将获得额外的荣誉 :-)。

最佳答案

DeleteGlobalRef() 释放引用,而不是对象。

如果那是最后一个可达的引用,那么引用的对象可用于垃圾回收。

Is a "GlobalReference" on an object just a reference count to the object

没有。它只是一个引用,在您明确释放它之前一直有效。 Java 的垃圾回收根本不依赖于引用计数。

另见 Oracle's documentation on global references .

关于java - 如果调用 JNI DeleteGlobalRef(),相应的 java 对象是否会被垃圾回收?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4337494/

相关文章:

java - 通知用户如果互联网不存在连接它做进一步的过程

c++ - 使用 STL 置换 std::vector 元素的最短解决方案

java - 哪个 native Windows 库处理文件、文件大小、创建日期? (与 JNI 一起使用)

java - OpenCV Java JNIEXPORT 内存管理

java - JRadioButton 调用选项

java - 使用 Spock 进行测试 - 使用复杂的数据提供程序

java - 访问数组列表中对象的元素

c++ - 捆绑应用程序中的动态库和框架

c++ - 立即在排序位置放置一个值

c - 在结构中使用 Option<unsafe fn ...> 的奇怪内存布局