在阅读JDK源代码时,我发现有些方法是native的,但是它们的静态 block 中没有System.loadLibrary
或System.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/