Я изучаю, как работает jvm. Сейчас пытаюсь понять в какой момент запускать rt.jar загружается в ВМ. И где в коде это посмотреть?
Как rt.jar загружается в jvm - точку доступа?
Ответы (1)
Это зависит от того, что вы на самом деле подразумеваете под 'rt.jar загружается в виртуальную машину'. HotSpot не загружает все rt.jar памяти. Вместо этого он лениво ищет соответствующую запись JAR всякий раз, когда загрузчик классов начальной загрузки пытается загрузить класс. Иногда JVM даже не требуется доступ к jar для загрузки системного класса, например. при использовании архива CDS. Также обратите внимание, что с JDK 9 больше нет rt.jar — вместо этого есть модульные изображения.
Простой способ узнать, когда/где 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
Здесь мы видим точную трассировку стека, где JVM впервые открывает rt.jar. Это происходит во время начальной загрузки JVM при инициализации системного словаря для предварительной загрузки системного класса.
Теперь эти функции легко найти в исходном коде.< br /> classLoader. cpp — хорошее место для начала.