rt.jar 如何加载到 jvm - 热点?

Amo*_*mos 1 jvm-hotspot

我正在学习 jvm 的工作原理。现在我想弄清楚在什么时候运行 rt.jar 被加载到 VM 中。我可以在代码中的哪个位置看到它?

apa*_*gin 5

这取决于您所说的'rt.jar is loaded into the VM' 的实际含义。HotSpot 不会将整个加载rt.jar内存中。相反,每当引导类加载器尝试加载类时,它都会惰性地查找相应的 JAR 条目。有时 JVM 甚至不需要访问 jar 来加载系统类,例如在使用CDS 存档时。另请注意,rt.jar自 JDK 9 以来不再有 -而是有模块化图像

查找 JVM 首次打开的时间/位置的一种简单方法rt.jar是在调试器下运行 Java 并在ZIP_Open.

Breakpoint 1, 0x00007ffff5632880 in ZIP_Open () from /usr/java/jdk8u275/jre/lib/amd64/libzip.so
(gdb) bt
#0  0x00007ffff5632880 in ZIP_Open () from /usr/java/jdk8u275/jre/lib/amd64/libzip.so
#1  0x00007ffff67d65cb in ClassLoader::create_class_path_entry(char const*, stat const*, bool, bool, Thread*) () from /usr/java/jdk8u275/jre/lib/amd64/server/libjvm.so
#2  0x00007ffff67d6ba1 in LazyClassPathEntry::open_stream(char const*, Thread*) () from /usr/java/jdk8u275/jre/lib/amd64/server/libjvm.so
#3  0x00007ffff67d8b99 in ClassLoader::load_classfile(Symbol*, Thread*) () from /usr/java/jdk8u275/jre/lib/amd64/server/libjvm.so
#4  0x00007ffff6e32e9f in SystemDictionary::load_instance_class(Symbol*, Handle, Thread*) () from /usr/java/jdk8u275/jre/lib/amd64/server/libjvm.so
#5  0x00007ffff6e3397e in SystemDictionary::resolve_instance_class_or_null(Symbol*, Handle, Handle, Thread*) () from /usr/java/jdk8u275/jre/lib/amd64/server/libjvm.so
#6  0x00007ffff6e34f93 in SystemDictionary::initialize_wk_klasses_until(SystemDictionary::WKID, SystemDictionary::WKID&, Thread*) () from /usr/java/jdk8u275/jre/lib/amd64/server/libjvm.so
#7  0x00007ffff6e35165 in SystemDictionary::initialize_preloaded_classes(Thread*) () from /usr/java/jdk8u275/jre/lib/amd64/server/libjvm.so
#8  0x00007ffff6e355a8 in SystemDictionary::initialize(Thread*) () from /usr/java/jdk8u275/jre/lib/amd64/server/libjvm.so
#9  0x00007ffff6e84928 in Universe::genesis(Thread*) () from /usr/java/jdk8u275/jre/lib/amd64/server/libjvm.so
#10 0x00007ffff6e8596c in universe2_init() () from /usr/java/jdk8u275/jre/lib/amd64/server/libjvm.so
#11 0x00007ffff69d5248 in init_globals() () from /usr/java/jdk8u275/jre/lib/amd64/server/libjvm.so
#12 0x00007ffff6e6a38d in Threads::create_vm(JavaVMInitArgs*, bool*) () from /usr/java/jdk8u275/jre/lib/amd64/server/libjvm.so
#13 0x00007ffff6aae50f in JNI_CreateJavaVM () from /usr/java/jdk8u275/jre/lib/amd64/server/libjvm.so
#14 0x00007ffff79aefa0 in JavaMain () from /usr/java/jdk8u275/bin/../lib/amd64/jli/libjli.so
#15 0x00007ffff7bc6e65 in start_thread () from /lib64/libpthread.so.0
#16 0x00007ffff74d388d in clone () from /lib64/libc.so.6
Run Code Online (Sandbox Code Playgroud)

在这里,我们看到了确切的堆栈跟踪,即 JVM 首先打开的位置rt.jar。这发生在 JVM 引导期间,在初始化系统字典以预加载系统类时。

现在很容易在源代码中找到这些函数。
classLoader.cpp是一个很好的起点。