Search code examples
java-native-interface

Do I need to DeleteLocalRef a jstring object returned by JNI call?


Suppose I'm using JNI to call some Java method that returns String, i. e. jstring in native code:

jstring jStr = (jstring)env->CallStaticObjectMethod(myApplicationClass, getString);

Do I then need to call env->DeleteLocalRef(jStr)? I think I do, but I can't find any specific instructions that state so in the JNI reference, and I can see I have a lot of code that doesn't call it - tried and true code. But if there was a minor memory leak, no one would notice since this code doesn't create many objects.


Solution

  • Every local reference you create is automatically freed when your JNI-called function returns to Java.

    The JNI specification outlines two cases where you might want to use DeleteLocalRef:

    A native method accesses a large Java object, thereby creating a local reference to the Java object. The native method then performs additional computation before returning to the caller. The local reference to the large Java object will prevent the object from being garbage collected, even if the object is no longer used in the remainder of the computation.

    In other words, if you allocated a multi-megabyte string and no longer need it, you can delete the reference immediately, instead of leaving it to the JVM when you return to it. However, this is only useful if you need to perform additional steps in the JNI world before returning.

    Note that this situations talks about a JNI function that is called from Java. By attaching native threads to the JVM you can end up in the reverse situation, where your native code calls into the JVM. In that situation the JVM will not auto-free your local references and you need to delete local references yourself.

    As a concrete example of that case, all the local references created in this function in the JNI cookbook will linger; they are never cleaned up manually.

    A native method creates a large number of local references, although not all of them are used at the same time. Since the VM needs a certain amount of space to keep track of a local reference, creating too many local references may cause the system to run out of memory. For example, a native method loops through a large array of objects, retrieves the elements as local references, and operates on one element at each iteration. After each iteration, the programmer no longer needs the local reference to the array element.

    This one is simpler: there is an upper limit to the number of local references.