Disclosed is a technique for eliminating expensive round trips when calls are made to DeleteLocalRef in a split Java* Virtual Machine (JVM). In a split JVM the cost of the calls between Java and native code have much greater overhead and latency resulting in the need to reduce round-trips where possible. When code is written using the Java Native Interface (JNI) a common pattern is to use GetObjectArrayElement to get the elements in an array. Each time an element is returned by GetObjectArrayElement a local reference is created. If the size of the array is large, this can lead to many local references being created and live at the same time. Too many concurrent local references can lead to poorer JVM performance or even application failures if the number that can be supported by the JVM is exceeded. Best practice, is therefore, to call DeleteLocalRef after the local reference for each element is no longer needed. In a split JVM, however, applying this pattern will result in additional expensive round trips in order to communicate the request back to the JVM.
DeleteLocalReference roundtrip optimization when implementing JNI Offload in a JVM
Disclosed is a process for reducing or removing the overhead of an expensive round trip when DeleteLocalRef is called in an application using Java™ Native Interface (JNI).
Java Virtual Machine (JVM) implementations support the Java Native Interface as a mechanism which allows Java code to call methods written in other languages such as C and C++, referred to as native code and for native code to call Java code. Traditionally both the code written in Java and the native code is executed in the same process and by the same thread as execution transitions between the two programming languages.
It is possible, however, to construct a Java Virtual Machine such that the native code is run in one or more remote execution containers. The remote execution containers may be hosted in separate processes on the same or different machines from where the Java code is executed such that the native code is unaware that it is executing separately from the JVM. This separation
p
revents misbehaved native code from destabilizing the JVM and enables running the native code in a different environment, for example a security context, or bit width, than the main JVM.
When using Java Native Interface a common pattern is to use GetObjectArrayElement to get the elements in an array. Each time an element is returned by GetObjectArrayElement a local reference is created. When the size of the array is large, many local references may be created and exist concurrently. Too many concurrent local references can lead to degraded JVM
p
erformance or even application failures when the number of references that can be supported by the JVM is exceeded. Best practice, is therefore, to call DeleteLocalRef after the local reference for each element is no longer needed. In a split JVM, however, applying this pattern will result in additional expensive round trip calls to communicate the request back to the JVM.
The following code example illustrates typical round trips incurred when this pattern is used:
Native JVM
1: void workOnArray(JNIEnv* env, jobject obj, jarray array){
2: jint i;
3: jint count = (*env)->GetArrayLength(env, array);
4: for (i=0; i < count; i++) {
5: jobject element = (*env)->GetObjectArrayElement(env, array, i);
6: if((*env)->ExceptionOccurred(env)) {
7: break;
8: }
9:
10: /* do something with array element */
11:
12: /* delete the local ref */
13: (*env)-> DeleteLocalRef(env,element);
14: }
15: }
GetArrayLength
GetObjectArrayElement
ExceptionCheck
DeleteLocalRef
1
The element in the example is the local reference. As shown in the example in a split JVM the call to DeleteLocalRef will incur an additional round trip, illustrated by line 13, to communicate the request back to the JVM for each element in the array.
The disclosed process comprises three parts providing a capability to remove the expensive round trip for the DeleteLoc...