What are the usual steps that the JVM runtime has to perform when calling a Java method that is declared as native
?
How does a HotSpot 1.8.0 JVM implement a JNI function call? What checking steps are involved (e.g. unhandled exceptions after return?), what bookkeeping has the JVM to perform (e.g. a local reference registry?), and where does the control go after the call of the native Java method? I would also appreciate it if someone could provide the entry point or important methods from the native HotSpot 1.8.0 code.
Disclaimer: I know that I can read the code myself but a prior explanation helps in quickly finding my way through the code. Additionally, I found this question worthwhile to be Google searchable. ;)
Native methods are Java™ methods that start in a language other than Java. Native methods can access system-specific functions and APIs that are not available directly in Java. The use of native methods limits the portability of an application, because it involves system-specific code.
The Java Native Interface (JNI) establishes a well-defined and platform-independent interface between the two. Native code can be used together with Java in two distinct ways: as "native methods" in a running JVM and as the code that creates a JVM using the "Invocation API".
Native methods are platform-specific code. They are usually written in languages such as C or C++ and contained in libraries(dll's). It is possible to create a hybrid Java application that benefits from such libraries. Reasons for Using Native Methods.
Now,In case Java application, when JVM encounters any use of such service in your program, it uses system calls exposed by OS. To use/call these system calls, JVM maintains another stack with Java stack called "Native method stack" (like C application stack) with every running thread of your Java application.
JVM is a part of JRE (Java Runtime Environment). Java applications are called WORA (Write Once Run Anywhere). This means a programmer can develop Java code on one system and can expect it to run on any other Java-enabled system without any adjustment. This is all possible because of JVM.
JNI is the tool that we use when we have to bridge between the virtual machine world, and the world of C, C++, etc.. The reverse is also true. It is not possible to actually get a JVM running without using JNI.
When you run java.exe, then there are a couple of Java Native Interface (JNI) calls. These calls load the DLL that is really the JVM (that’s right – java.exe is NOT the JVM). JNI is the tool that we use when we have to bridge between the virtual machine world, and the world of C, C++, etc..
Calling a JNI method from Java is rather expensive comparing to a simple C function call. HotSpot typically performs most of the following steps to invoke a JNI method:
JNIEnv*
and jclass
for static methods and pass them as additional arguments.method_entry
trace function.synchronized
.in_java
to in_native
state.in_java
state.method_exit
.The source code for this procedure can be found at SharedRuntime::generate_native_wrapper.
As you can see, an overhead may be significant. But in many cases most of the above steps are not necessary. For example, if a native method just performs some encoding/decoding on a byte array and does not throw any exceptions nor it calls other JNI functions. For these cases HotSpot has a non-standard (and not known) convention called Critical Natives
, discussed here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With