调用本地方法时,JVM必须做什么?
当调用一个声明为native
的Java方法时,JVM运行时必须执行的常规步骤是什么?
HotSpot 1.8.0 JVM如何实现JNI函数调用? 涉及哪些检查步骤(例如,返回后的未处理exception?),JVM要执行哪些簿记(例如,本地引用registry?)以及控制在本地Java方法调用之后的位置? 如果有人能够提供本地HotSpot 1.8.0代码的入口点或重要方法,我也将非常感激。
免责声明:我知道我可以自己阅读代码,但事先的解释有助于快速find我的代码。 另外,我发现这个问题值得Googlesearch。 ;)
与简单的C函数调用相比,从Java调用JNI方法相当昂贵。 HotSpot通常执行以下大多数步骤来调用JNI方法:
- 创build一个堆栈帧。
- 根据ABI将参数移动到正确的寄存器或堆栈位置。
- 将对象引用包装为JNI句柄。
- 获取静态方法的
JNIEnv*
和jclass
,并将它们作为附加parameter passing。 - 检查是否应该调用
method_entry
trace函数。 - 如果方法已
synchronized
则locking对象监视器。 - 检查本地函数是否已链接。 函数查找和链接是懒惰地执行的。
- 将线程从
in_java
切换到in_native
状态。 - 调用本地函数
- 检查是否需要安全点。
- 将线程返回到
in_java
状态。 - 解锁监视器,如果locking。
- 通知
method_exit
。 - 解包对象结果并重置JNI处理块。
- 处理JNIexception。
- 删除堆栈框架。
这个过程的源代码可以在SharedRuntime :: generate_native_wrapperfind。
正如你所看到的,开销可能很大。 但是在很多情况下,大部分上述步骤都是不必要的。 例如,如果一个本地方法只是对一个字节数组执行一些编码/解码,并且不会抛出任何exception,也不会调用其他的JNI函数。 对于这些情况,HotSpot有一个称为“ Critical Natives
的非标准(不知道)约定,在这里讨论。
- 如何使用JodaTime获取特定月份的最后date?
- Maven错误:无法find或加载主类org.codehaus.plexus.classworlds.launcher.Launcher
- 无论如何排除从父POMinheritance的工件?
- 如何将org.w3c.dom.Document对象转换为string?
- 何时通过LinkedList或ArrayList使用HashMap,反之亦然
- 是否有可能在Java 8中投射stream?
- java.lang.ClassNotFoundException:在path上找不到类:dexpathlist
- 在IntelliJ IDEA中如何添加像-ea这样的编译器选项?
- Java:如何检查对象是否为空?