java - JDK 的本地方法是如何加载的?

标签 java jvm java-native-interface

在阅读JDK源代码时,我发现有些方法是native的,但是它们的静态 block 中没有System.loadLibrarySystem.load,那么那些方法是怎样的呢?实际加载的方法?

所以我猜这些方法是内置在 JVM 中的。只是想知道它们是如何为特定类(class)加载的。比如,StrictMath。如下:

public final StrictMath {
    public static native double cos(double a);
}

所以我可以找到这个本地方法的源代码,只是想知道它是如何为这个特定的类加载的。

最佳答案

所有 native 方法的绑定(bind)在第一次调用时延迟执行,除非这些方法之前通过调用 JNI 显式绑定(bind) RegisterNatives功能。

因此,在第一次调用本地方法时,JVM 要求动态链接器在其中一个加载的共享库中找到名为 Java_package_Class_method 的符号。例如,在 Linux 上调用 dlsym完成工作。

对于StrictMath方法,不需要调用System.loadLibrary,因为带有StrictMath符号的共享库( Linux 上的 libjava.so 或 Windows 上的 java.dll)已经加载。实际上,JVM 在启动阶段的早期就加载了 libjava.so,因为该库包含 VM 引导所需的核心 Java 方法的 native 实现。

检查libjava.so包含哪些符号:

$ nm /usr/java/jdk-11.0.1/lib/libjava.so | grep Java_

....
00000000000146c0 T Java_java_lang_StrictMath_acos
00000000000146b0 T Java_java_lang_StrictMath_asin
00000000000146d0 T Java_java_lang_StrictMath_atan
0000000000014710 T Java_java_lang_StrictMath_atan2
0000000000014680 T Java_java_lang_StrictMath_cos
0000000000014730 T Java_java_lang_StrictMath_cosh
0000000000014770 T Java_java_lang_StrictMath_expm1
...

关于java - JDK 的本地方法是如何加载的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54085467/

相关文章:

java - kafka java 客户端不消费 - 只是卡在 consumer.poll

java - 为什么 JVM 不使用更多的堆内存

java - 使用 MinGW C++ 编译 64 位静态库以用于 Java (JNI)

java - 如何在 Eclipse 中创建自定义 GUI 控件以用于 Android 应用程序布局?

java - 如何在 jar 文件中使用 Tika 自定义解析器?

java - Java 类型删除会删除我的泛型类型吗?

java - 编译静态链接的 netty-tcnative 失败,与来自 JDK 的 jni.h 不匹配

java - 如何将 Java 空参数传递给使用 JNA 编译为 C 代码的 native 方法?

Java 抽象、泛型和构建器

java - 新启动的 JVM 的方法级分析