如何加载JDK的本机方法?

时间:2019-01-08 05:01:12

标签: java jvm java-native-interface

在阅读JDK源代码时,我发现有些方法是本机的,但是它们的静态块中没有$cars=array("09:00","11:00","11:30","12:00","12:30"); echo "<pre>";print_R($cars); $pos = array_search('10:30', $cars); unset($cars[$pos]); echo "<pre>";print_r($cars); ,那么这些方法是如何实际加载的?

所以我想那些方法是内置在JVM中的。只是想知道如何为特定类加载它们。说System.loadLibrary。如下:

System.load

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

2 个答案:

答案 0 :(得分:3)

除非在第一次调用JNI RegisterNatives函数时显式地绑定了这些方法,否则所有本机方法的绑定都是在第一次调用时延迟执行的。

因此,在首次调用本机方法时,JVM要求动态链接器在已加载的共享库之一中找到名为Java_package_Class_method的符号。例如,在Linux上,调用dlsym即可完成这项工作。

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

检查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
...

答案 1 :(得分:1)

我相信这是Bootstrap Classloader的责任(负责从java.lang包中加载关键的Java类),它是用本机代码编写的。