简体   繁体   English

JNI-谁释放Java方法返回的ByteBuffer?

[英]JNI - Who frees ByteBuffer returned by a Java method?

I understand when a call is made from Java to C, there is no need to release memory obtained by GetDirectBufferAddress method. 我知道从Java到C进行调用时,不需要释放通过GetDirectBufferAddress方法获得的内存。 The garbage collector knows when to reclaim the memory. 垃圾收集器知道何时回收内存。 In my case, I am calling a Java method from C. Here is a code snippet for my Java method: 就我而言,我是从C调用Java方法。这是我的Java方法的代码段:

ByteBuffer processTask() {
   ...
   ByteBuffer retVal = ByteBuffer.allocateDirect(len);
   return retVal;
}

Here is a code snippet from my C function: 这是我的C函数的代码片段:

jobject retVal = invokeProcessTask();
uint8_t* buf = (uint8_t*) env->GetDirectBufferAddress(retVal);

In this case, I am thinking the garbage collector has no idea when to collect the ByteBuffer instance. 在这种情况下,我认为垃圾收集器不知道何时收集ByteBuffer实例。 I am thinking it will be my C code's responsibility to release this memory. 我认为释放此内存将是我的C代码的责任。 Is this right? 这是正确的吗? If so, what function do I need to call to release it? 如果是这样,我需要调用什么函数来释放它? Regards. 问候。

The JNI docs do not seem to make this clear. JNI文档似乎并不清楚。 They do say that all Java objects returned by JNI functions are local references, and I see no reason to doubt that that applies whether or not the JNI function is called inside the scope of a broader native method invocation. 他们确实说JNI函数返回的所有Java对象都是本地引用,并且我认为没有理由怀疑是否在更广泛的本机方法调用的范围内调用JNI函数。 The VM is responsible for keeping track of objects passed to native code, so as not to GC them while still in use, and I think it's necessary to interpret "passed" as including "returned to". VM负责跟踪传递给本机代码的对象,以免在仍在使用它们时对其进行GC,并且我认为有必要将“通过”解释为包括“返回给”。

I am therefore inclined to agree with the interpretation that when a Java VM is embedded in a C program, and the program obtains a reference to a Java object by calling a JNI function outside the scope of a Java -> C native method invocation, that the referred-to object and all those reachable from it remain ineligible for GC until the C program explicitly releases its reference (at least). 因此,我倾向于同意这样的解释:当Java VM嵌入在C程序中,并且该程序通过在Java-> C本机方法调用范围之外调用JNI函数来获得对Java对象的引用时,在C程序显式释放其引用之前(至少),所引用的对象以及从该对象可访问的所有对象均不具有GC资格。 The program can release local references via the DeleteLocalRef() function. 该程序可以通过DeleteLocalRef()函数释放本地引用。

Note, too, JNI provides for only a limited number of local references to live in the same JNI environment at any given time. 还要注意,JNI在任何给定时间仅提供有限数量的本地引用来驻留在同一JNI环境中。 That number can be managed via EnsureLocalCapacity() , PushLocalFrame() , and PopLocalFrame() , but you must take care to avoid exceeding it, which may be more of a risk in the embedding scenario you describe than it is in a short-running, narrow-scoped native method invocation. 可以通过EnsureLocalCapacity()PushLocalFrame()PopLocalFrame()来管理该数字,但是您必须小心避免超过该数字,这在您描述的嵌入方案中可能比短期运行更具风险。 ,范围狭窄的本机方法调用。

您可以调用DeleteLocalRef() ,但是除非C方法真正长时间运行,否则可能不需要:GC可以在JNI方法返回后的任何时间收集它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM