调用本机方法时JVM必须做什么?

box*_*box 16 java java-native-interface jvm

在调用声明为的Java方法时,JVM运行时必须执行的常规步骤是native什么?

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

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

apa*_*gin 36

与简单的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,在讨论.