JVM 在调用本机方法时必须执行哪些操作?

2022-09-02 03:02:47

JVM 运行时在调用声明为 ?native

HotSpot 1.8.0 JVM 如何实现 JNI 函数调用?涉及哪些检查步骤(例如,返回后未处理的异常?),JVM要执行哪些簿记(例如本地引用注册表?),以及调用本机Java方法后控件的去向?如果有人能从本机HotSpot 1.8.0代码中提供入口点或重要方法,我将不胜感激。

免责声明:我知道我可以自己阅读代码,但事先的解释有助于快速找到我通过代码的方式。此外,我发现这个问题值得谷歌搜索。;)


答案 1

与简单的 C 函数调用相比,从 Java 调用 JNI 方法相当昂贵。HotSpot 通常执行以下大部分步骤来调用 JNI 方法:

  1. 创建堆栈帧。
  2. 根据 ABI 将参数移动到正确的寄存器或堆栈位置。
  3. 包装对 JNI 句柄的对象引用。
  4. 获取 和 对于静态方法,并将其作为附加参数传递。JNIEnv*jclass
  5. 检查是否应该调用跟踪函数。method_entry
  6. 如果方法是 锁定对象监视器(如果该方法是 )。synchronized
  7. 检查本机函数是否已链接。函数查找和链接执行得很懒惰。
  8. 将线程从切换到状态。in_javain_native
  9. 调用本机函数
  10. 检查是否需要安全点。
  11. 将线程返回到状态。in_java
  12. 如果锁定,请解锁显示器。
  13. 通知。method_exit
  14. 解包对象结果并重置 JNI 处理块。
  15. 处理 JNI 异常。
  16. 移除堆栈框架。

此过程的源代码可以在 SharedRuntime::generate_native_wrapper 中找到。

如您所见,开销可能很大。但在许多情况下,上述大多数步骤都不是必需的。例如,如果本机方法只是在字节数组上执行一些编码/解码,并且不引发任何异常,也不调用其他 JNI 函数。对于这些情况,HotSpot 有一个非标准(和未知)约定,称为 ,在这里讨论。Critical Natives


答案 2

推荐