Should you call ReleaseStringUTFChars if GetStringUTFChars returned a copy?
Yes, your assumption is correct (you should always call ReleaseStringUTFChars).
If I don't call ReleaseStringUTFChars, will it be automatically called at the end of the JNI call?
I looked at 'Should you call ReleaseStringUTFChars if GetStringUTFChars
returned a copy?', and while it claims you should always call
ReleaseStringUTFChars(), it doesn't explicitly say that not doing so
will create a memory leak that persists for the duration of the
program.
I would interpret that to mean that if ReleaseStringUTFChars()
is not called, then the memory won't be reclaimed. JNI can't automatically reclaim the memory, because your code might have retained a pointer to it (perhaps for use in the next invocation). It's not necessary to call the release() from the same stack frame as the get(), but you will want to arrange that it is called at some point (unless you know you're about to exit).
Must ReleaseStringUTFChars be called after GetStringUTFChars (when passing the char* to C function)?
The Get Characters function pins the characters in memory until the Release method is called. Java is unable to garbage collect or otherwise move this data until it is sure that no-one is using it.
The Java VM can not know anything about how long the memory will be used for once it leaves the Java virtual machine, therefore it requires manual notification that the memory has been finished with.
How GetStringUTFChars and ReleaseStringUTFChars works?
isCopy
parameter for GetStringUTFChars()
is only an attempt to provide a signature consistent with other similar JNI functions. In all known JVM implementations it is always invariably JNI_TRUE
, because the Java strings are stored internally in an incompatible UCS-16 format.
But still, you cannot release cstr
without knowing the context.
GetStringUTFChars and its string copy behavior
According to the book "Essential JNI Java Native Interface", it is the implementation of the JVM that decides whether a copy is done or not. So no, you have no control over the copying.
Should I use ReleaseStringUTFChars if I want to return the C sting obtained from GetStringUTFChars?
GetStringUTFChars
will allocate memory for the string it returns, and ReleaseStringUTFChars
frees that memory. So you should call ReleaseStringUTFChars
when you're done using the data that GetStringUTFChars
returned.
Java JNI GetStringUTFChars
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.
Related Topics
Why Does Intellij Give Me "Package Doesn't Exist" Error
When Not to Use the Static Keyword in Java
When Do You Need to Explicitly Call a Superclass Constructor
Java Generic Class - Determine Type
Java Raw Type and Generics Interaction
Are There Any Java Method Ordering Conventions
Parsing JSON Array Within JSON Object
Displaying Fancy Equations with Java
How to Change Java Version Used by Tomcat
Change Database Schema Used by Spring Boot
Create Whole Path Automatically When Writing to a New File
Is 1/0 a Legal Java Expression
What Is Java_Home? How Does the Jvm Find the Javac Path Stored in Java_Home
Jpa, How to Use the Same Class (Entity) to Map Different Tables
Why Does Java App Crash in Gdb But Runs Normally in Real Life
What to Return If Spring MVC Controller Method Doesn't Return Value