(以下の内容はほとんど HotSpot Runtime Overview の受け売り. こちらも参照のこと)
JNI_CreateJavaVM() による HotSpot の起動処理は以下のようになる.
(現状の実装では, 1プロセス内に最大1つしか HotSpot は生成させない)
(ちなみに, 初期化プロセスが "point of no return" という点まで到達すると, 再初期化不可能な static なデータ構造を生成し終わるため, もう HotSpot は作れなくなる. この検査は, そこに到達する前に別のスレッドが JNI_CreateJavaVM() を呼んだ場合用のチェック)
Threads::create_vm() を呼び出す. この中で初期化処理の大半が行われる.
(e.g. synchronization, stack, memory, safepoint pages, etc).
(また, その他のライブラリ(libzip, libjava, etc) をロードしたり, シグナルハンドラを初期化したりもする) 1. ostream_init_log() で, output stream logger を初期化する.
(必要な agent libraries (hprof, jdi) も初期化してスタートさせる) 1. ThreadLocalStorage::init() 等で, スレッドの状態や TLS などを初期化する. 1. vm_init_globals() で, 大域データを初期化する.
(e.g. event log, OS synchronization primitives, perfMemory (performance memory), chunkPool (memory allocator), etc) 1. この段階でスレッドが作れるようになる.
Java の main スレッドが作られ, 現在実行中のネイティブスレッドに対応付けられる (ただし, このスレッドは the known list of the Threads には追加されない ??)
ちなみに, ここが "point of no return" (set_as_starting_thread() の途中で失敗したらやり直せない) 1. ObjectMonitor::Initialize() で, Java レベルの同期排他機構の初期化を行う. 1. init_globals() で, 残りの大域モジュールを初期化する.
(e.g. BootClassLoader, CodeCache, Interpreter, Compiler, JNI, SystemDictionary, Universe, etc)
ちなみに, ここも "point of no return" (init_globals() の途中で失敗したらやり直せない) 1. main スレッドが list (the known list of the Threads??) に追加される.
(<= なお Thread_Lock(??) を最初にロックするはこの時らしい) 1. Universe::verify() で, Universe のチェックを行う. 1. VMThread::create() で, VMThread を生成する. 1. 現在の状態を知らせるための適切な JVMTI イベントが発行される. 1. initialize_class() を用いて, 種々の Java クラスがロードされ初期化される.
(e.g. java.lang.String, java.lang.System, java.lang.ThreadGroup, java.lang.Thread, java.lang.reflect.Method, java.lang.ref.Finalizer, java.lang.Class, and the rest of the System)
なお HotSpot 内では, C++ の global initializer 等は使用していない.
代わりに, 明示的に初期化用関数を用意し, vm_init_globals() や init_globals() から呼び出すという構成にしている.
コメントによると, 「この方がリンク時間が少なくとも2倍は速くなるし, 初期化の順番もコントロールできるため」とのこと.
このため新しくモジュールを追加する場合にも, 「グローバルにオブジェクトを確保するのではなく, ポインタを入れる場所だけ確保しておいて, 明示的に初期化用関数を init.cpp 内で呼び出すように」, とのこと.
((cite: hotspot/src/share/vm/runtime/init.hpp))
// init_globals replaces C++ global objects so we can use the standard linker
// to link Delta (which is at least twice as fast as using the GNU C++ linker).
// Also, init.c gives explicit control over the sequence of initialization.
// Programming convention: instead of using a global object (e,g, "Foo foo;"),
// use "Foo* foo;", create a function init_foo() in foo.c, and add a call
// to init_foo in init.cpp.
jint init_globals(); // call constructors at startup (main Java thread)
void vm_init_globals(); // call constructors at startup (VM thread)
void exit_globals(); // call destructors before exit
JNI_CreateJavaVM() -> Threads::create_vm() (← この中で実際の初期化処理の大半が行われる) -> -> ostream_init() -> -> os::init() -> -> Arguments::parse() -> -> os::init_2() -> -> ostream_init_log() -> -> ThreadLocalStorage::init() -> -> vm_init_globals() -> check_ThreadShadow() -> basic_types_init() -> eventlog_init() -> mutex_init() -> chunkpool_init() -> perfMemory_init() -> -> ObjectMonitor::Initialize() -> -> init_globals() -> management_init() -> bytecodes_init() (See: here for details) -> classLoader_init() (See: here for details) -> codeCache_init() -> VM_Version_init() -> stubRoutines_init1() -> universe_init() (See: here for details) -> interpreter_init() (See: here for details) -> invocationCounter_init() -> marksweep_init() -> accessFlags_init() -> templateTable_init() (See: here for details) -> InterfaceSupport_init() -> SharedRuntime::generate_stubs() -> universe2_init() -> Universe::genesis() -> referenceProcessor_init() (See: here for details) -> jni_handles_init() -> vmStructs_init() -> vtableStubs_init() -> InlineCacheBuffer_init() -> compilerOracle_init() -> compilationPolicy_init() (See: here for details) -> VMRegImpl::set_regName() -> universe_post_init() -> javaClasses_init() -> stubRoutines_init2() -> -> Universe::verify() -> -> VMThread::create() (See: here for details) -> -> initialize_class() (See: here for details) -> -> quicken_jni_functions() (See: here for details) -> ... #TODO -> -> CompileBroker::compilation_init() (See: here for details) -> Management::initialize() (See: here for details) -> FlatProfiler::engage() -> AllocationProfiler::engage() -> MemProfiler::engage() -> StatSampler::engage() -> JniPeriodicChecker::engage() -> BiasedLocking::init() (See: here for details) -> WatcherThread::start() -> os::init_3()
See: here for details
See: here for details
(#Under Construction)
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.