getElementsCritical

The semantics of this function is very similar to the getElements. If possible, the VM returns a pointer to the primitive array; otherwise, a copy is made. However, there are significant restrictions on how these functions can be used.

After calling getElementsCritical, the native code should not run for an extended period of time before it calls releaseElementsCritical. We must treat the code inside this pair of functions as running in a "critical region." Inside a critical region, native code must not call other JNI functions or any system call that may cause the current thread to block and wait for another Java thread. (For example, the current thread must not call read on a stream being written by another Java thread.)

These restrictions make it more likely that the native code will get an uncopied version of the array, even if the VM does not support pinning. For example, a VM may temporarily disable garbage collection when the native code is holding a pointer to an array obtained via getElementsCritical.

Multiple pairs of getElementsCritical and releaseElementsCritical may be nested. For example:

val arr1: JByteArray = // ...
val arr2: JByteArray = // ...
val len = arr1.length
val (a1, _) = arr1.getElementsCritical() ?: error("out of memory exception thrown")
val (a2, _) = arr2.getElementsCritical() ?: error("out of memory exception thrown")
memcpy(a1, a2, len.toULong())
arr1.releaseElementsCritical(a1, ApplyChangesMode.FinalCommit)
arr2.releaseElementsCritical(a2, ApplyChangesMode.FinalCommit)

Note that getElementsCritical might still make a copy of the array if the VM internally represents arrays in a different format. Therefore, we need to check its return value against null for possible out-of-memory situations.

Since

JDK/JRE 1.2