(以下の内容はほとんど 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.