使用JNIEnv :: FindClass:我是否需要释放返回的jclass引用?

时间:2014-05-19 15:07:58

标签: c++ java-native-interface

假设我在JNI函数中有这个代码,它实现了一个native函数存根:

JNIEnv* env; /*This is set to a valid JNIEnv* for this thread*/
jclass clz = env->FindClass("foo"); /*this has worked*/

我是否需要致电

env->DeleteLocalRef(clz);

一旦我完成了它?我没有将clz返回给Java,所以我认为我需要删除本地引用?这似乎有点奇怪,因为像MethodID一样,jclass不包含对象实例。

2 个答案:

答案 0 :(得分:4)

调用DeleteLocalRef永远不会出错,所以你应该总是调用它,否则你可能会遇到本地引用数用尽的情况。

当您从Java调用JNI代码并且它的运行时间很短时,您可能很幸运,在您返回Java调用者后,本地引用会被清除,但是如果您是从本机代码调用Java VM(因此没有“外部”Java VM框架从中调用JNI代码),然后您将快速耗尽本地变量,因为它们永远不会被不存在的Java调用者删除

引用official Java documentation

在大多数情况下,程序员应该依赖VM在本机方法返回后释放所有本地引用。但是,有时程序员应该明确地释放本地引用。例如,考虑以下情况:

  • 本机方法访问大型Java对象,从而创建对Java对象的本地引用。然后,本机方法在返回调用方之前执行其他计算。对大型Java对象的本地引用将阻止对象被垃圾回收,即使该对象不再用于计算的其余部分。
  • 本机方法会创建大量本地引用,但并非所有引用都同时使用。由于VM需要一定的空间来跟踪本地引用,因此创建太多本地引用可能会导致系统内存不足。例如,本机方法循环遍历大量对象,将元素作为本地引用检索,并在每次迭代时对一个元素进行操作。在每次迭代之后,程序员不再需要对数组元素的本地引用。

答案 1 :(得分:0)

不,您不需要致电DeleteLocalRef FindClass返回本地引用。所以没有必要删除。 JN将在JNI调用完成后自动执行此操作 但是如果你想要你可以删除本地参考。它应该没有任何区别。