1
votes

I am learning Java JNI and trying to understand the GetStringUTFChars & ReleaseStringUTFChars. Still i can't able to understand the ReleaseStringUTFChars. As per my understanding from some article, in most cases that the GetStringUTFChars return a reference to the original string data and not a copy. So actually the ReleaseStringUTFChars release the jstring or the const char* (if copied) or both.

I can get a better understanding if i get the answer to the below question.

In the below code do i need to call the ReleaseStringUTFChars in a for loop or only once (with any one of the const char*)?

#define array_size 10
const char* chr[array_size];
jboolean blnIsCopy;
for (int i = 0; i < array_size; i++) {
    chr[i] = env->GetStringUTFChars(myjstring, &blnIsCopy);
    printf((bool)blnIsCopy ? "true\n" : "false\n"); //displays always true
    printf("Address = %p\n\n",chr[i]); //displays different address
}

//ReleaseStringUTFChars with in a for loop or single statement is enough
for (int i = 0; i < array_size; i++) {
    env->ReleaseStringUTFChars(myjstring, chr[i]);
}

Thanks in advance.

1
You get 10 times "StringUTF8Chars" hence need 10 releases. I take it that the pointers are different? Or copy once in this artificial example.Joop Eggen

1 Answers

1
votes

Get/ReleaseStringUTFChars must always be called in pairs, regardless of whether a copy or not is returned.

In practice, you pretty much always get a copy (at least with the JVM implementations I checked: OpenJDK and Dalvik) so that the GC is free to move the original array. It obviously can't collect it because you've got a reference to the string but it'll still move objects around.

There is also a GetStringCritical/ReleaseStringCritical call pair, which will always attempt to return a pointer to the original array (though in theory it may still return a copy). This makes it faster but it comes at a cost: the GC must not move the array until you release it. Again, in practice this is usually implemented by establishing a mutex with the GC, and incrementing a lock count for Get and decrementing it for Release. This means these must be called in pairs too, otherwise the lock count will never get back to zero and GC will probably never run. Please note: Get/ReleaseStringCritical also comes with other limitations which are less relevant to this question but are no less important.