java - JVM 在调用本地方法时必须做什么?

标签 java jvm java-native-interface

当调用声明为 native 的 Java 方法时,JVM 运行时通常必须执行哪些步骤?

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

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

最佳答案

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

  1. 创建堆栈框架。
  2. 根据 ABI 将参数移动到适当的寄存器或堆栈位置。
  3. 将对象引用包装到 JNI 句柄。
  4. 为静态方法获取 JNIEnv*jclass 并将它们作为附加参数传递。
  5. 检查是否应该调用 method_entry 跟踪函数。
  6. 如果方法是同步,则锁定对象监视器。
  7. 检查 native 函数是否已链接。函数查找和链接是延迟执行的。
  8. 将线程从 in_java 状态切换到 in_native 状态。
  9. 调用原生函数
  10. 检查是否需要安全点。
  11. 将线程返回到 in_java 状态。
  12. 如果锁定则解锁监视器。
  13. 通知method_exit
  14. 解包对象结果并重置 JNI 句柄 block 。
  15. 处理 JNI 异常。
  16. 移除栈帧。

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

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

关于java - JVM 在调用本地方法时必须做什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24746776/

相关文章:

intellij-idea - "IDE has not been initialized yet"说 CLion/PyCharm/IntelliJ 无法启动

java - 动态类加载作为 permgen 的原因之一?

java - 在 java 中用 System.loadLibrary() 加载的 .dll 的搜索路径是什么?

java - Java 入门

java - 编译器能否通过泛型方法验证对象的泛型类型?

java - 相对于 JVM 的字符串池,在 Java 中创建一个字符串的时间成本是多少?

Java UncaughtExceptionHandler 使用 JNI 没有任何异常

java - 将函数指针转换为 long

java - 使用 m2eclipse 开发 Web 应用程序的首选方式

java - For 循环不终止