我必须 DeleteLocalRef 一个我调用了 NewGlobalRef 的对象吗?
Must I DeleteLocalRef an object I have called NewGlobalRef on?
我们知道,在 C/C++ 拥有的线程中创建 Java 个对象,我们负责根据需要调用 DeleteLocalRef
或 Push/Pop LocalFrame
。
我有一些代码,例如
jbyteArray buffer = env->NewByteArray((jsize)requiredSize);
longTermBufferReference = (jbyteArray)env->NewGlobalRef(buffer);
本机代码创建一个字节数组,它在多个 threads/calls 中重复使用,完成后,我在缓冲区上调用 DeleteGlobalRef
。
问题是,完成后我必须在 buffer
上调用 DeleteLocalRef,还是 GlobalRef 会完全拥有该对象?
The question is, must I call DeleteLocalRef on buffer when I'm done
不,您可以让它在您的 JNI 方法 returns 时自动删除,或者如果您使用它,则由 PopLocalFrame()
自动删除。但是本地引用是一种稀缺资源:如果你的 JNI 函数使用了很多,你应该尽快释放它们。
补充一下@EJP 所说的:只有当不再有(强)引用时,对象才有资格进行垃圾回收。当您执行 NewGlobalRef 时,您创建了对对象的第二个引用,将引用数量增加到 2。本地引用仍将存在。
当你的函数退出时它会被运行时删除,但假设你的函数很长。如果您调用 DeleteGlobalRef,您将删除全局引用,但局部引用仍不受影响。引用数:1。只有在删除这个之后,垃圾收集器才能声明该对象。
在垃圾收集系统中,没有对象所有权这样的东西。存在根对象引用和可从根直接或间接到达的对象引用。 (不考虑弱引用)。
JNI 局部引用和JNI 全局引用都是根引用。创建其他引用不会影响现有引用,也不会将它们从根引用列表中删除。
所以,是的,必须删除本地引用(就像必须删除全局引用一样)。您已经知道可以使用 DeleteLocalRef
或 PopLocalFrame
显式执行此操作,或者,当 JNI 本机方法 returns 时,JNI 会有效地自动调用 PopLocalFrame
。
我们知道,在 C/C++ 拥有的线程中创建 Java 个对象,我们负责根据需要调用 DeleteLocalRef
或 Push/Pop LocalFrame
。
我有一些代码,例如
jbyteArray buffer = env->NewByteArray((jsize)requiredSize);
longTermBufferReference = (jbyteArray)env->NewGlobalRef(buffer);
本机代码创建一个字节数组,它在多个 threads/calls 中重复使用,完成后,我在缓冲区上调用 DeleteGlobalRef
。
问题是,完成后我必须在 buffer
上调用 DeleteLocalRef,还是 GlobalRef 会完全拥有该对象?
The question is, must I call DeleteLocalRef on buffer when I'm done
不,您可以让它在您的 JNI 方法 returns 时自动删除,或者如果您使用它,则由 PopLocalFrame()
自动删除。但是本地引用是一种稀缺资源:如果你的 JNI 函数使用了很多,你应该尽快释放它们。
补充一下@EJP 所说的:只有当不再有(强)引用时,对象才有资格进行垃圾回收。当您执行 NewGlobalRef 时,您创建了对对象的第二个引用,将引用数量增加到 2。本地引用仍将存在。
当你的函数退出时它会被运行时删除,但假设你的函数很长。如果您调用 DeleteGlobalRef,您将删除全局引用,但局部引用仍不受影响。引用数:1。只有在删除这个之后,垃圾收集器才能声明该对象。
在垃圾收集系统中,没有对象所有权这样的东西。存在根对象引用和可从根直接或间接到达的对象引用。 (不考虑弱引用)。
JNI 局部引用和JNI 全局引用都是根引用。创建其他引用不会影响现有引用,也不会将它们从根引用列表中删除。
所以,是的,必须删除本地引用(就像必须删除全局引用一样)。您已经知道可以使用 DeleteLocalRef
或 PopLocalFrame
显式执行此操作,或者,当 JNI 本机方法 returns 时,JNI 会有效地自动调用 PopLocalFrame
。