hotspot/src/share/vm/memory/universe.cpp
jint Universe::initialize_heap() {
{- -------------------------------------------
(1) オプションに応じて適切な CollectorPolicy オブジェクトおよび CollectedHeap オブジェクトを作成する.
(生成した CollectedHeap オブジェクトは Universe::_collectedHeap フィールドに格納)
* UseParallelGC の場合:
* CollectorPolicy : 無し
(正確には GenerationSizer が CollectorPolicy に相当するが, 後で生成される)
* CollectedHeap : ParallelScavengeHeap()
* UseG1GC の場合:
* CollectorPolicy : G1CollectorPolicy_BestRegionsFirst()
* CollectedHeap : G1CollectedHeap()
* UseSerialGC の場合
* CollectorPolicy : MarkSweepPolicy()
* CollectedHeap : GenCollectedHeap()
* UseConcMarkSweepGC && UseAdaptiveSizePolicy の場合
* CollectorPolicy : ASConcurrentMarkSweepPolicy()
* CollectedHeap : GenCollectedHeap()
* UseConcMarkSweepGC && ! UseAdaptiveSizePolicy の場合
* CollectorPolicy : ConcurrentMarkSweepPolicy()
* CollectedHeap : GenCollectedHeap()
* それ以外の場合
* CollectorPolicy : MarkSweepPolicy()
* CollectedHeap : GenCollectedHeap()
---------------------------------------- -}
if (UseParallelGC) {
#ifndef SERIALGC
Universe::_collectedHeap = new ParallelScavengeHeap();
#else // SERIALGC
fatal("UseParallelGC not supported in java kernel vm.");
#endif // SERIALGC
} else if (UseG1GC) {
#ifndef SERIALGC
G1CollectorPolicy* g1p = new G1CollectorPolicy_BestRegionsFirst();
G1CollectedHeap* g1h = new G1CollectedHeap(g1p);
Universe::_collectedHeap = g1h;
#else // SERIALGC
fatal("UseG1GC not supported in java kernel vm.");
#endif // SERIALGC
} else {
GenCollectorPolicy *gc_policy;
if (UseSerialGC) {
gc_policy = new MarkSweepPolicy();
} else if (UseConcMarkSweepGC) {
#ifndef SERIALGC
if (UseAdaptiveSizePolicy) {
gc_policy = new ASConcurrentMarkSweepPolicy();
} else {
gc_policy = new ConcurrentMarkSweepPolicy();
}
#else // SERIALGC
fatal("UseConcMarkSweepGC not supported in java kernel vm.");
#endif // SERIALGC
} else { // default old generation
gc_policy = new MarkSweepPolicy();
}
Universe::_collectedHeap = new GenCollectedHeap(gc_policy);
}
{- -------------------------------------------
(1) 生成した CollectedHeap オブジェクトの CollectedHeap::initialize() メソッドを呼び出す.
もし失敗したらここでリターン.
---------------------------------------- -}
jint status = Universe::heap()->initialize();
if (status != JNI_OK) {
return status;
}
{- -------------------------------------------
(1) 以下は #ifdef _LP64 で UseCompressedOops オプションが指定されていた場合の処理.
ヒープのベースアドレス(Universe::narrow_oop_base()), 及び
ポインタのシフト幅(Universe::narrow_oop_shift())を設定する.
(これらの値はヒープ領域の終端アドレスに応じて決まる)
* ヒープ領域の終端アドレスが OopEncodingHeapMax を超えている場合
* Universe::narrow_oop_base() : ヒープのベースアドレス (から 1ページ分だけ引いたアドレス)
* Universe::narrow_oop_shift() : LogMinObjAlignmentInBytes
* ヒープ領域の終端アドレスが (OopEncodingHeapMax 以下だが) NarrowOopHeapMax を超えている場合
* Universe::narrow_oop_base() : 0
* Universe::narrow_oop_shift() : LogMinObjAlignmentInBytes
* ヒープ領域の終端アドレスが NarrowOopHeapMax 以下の場合
* Universe::narrow_oop_base() : 0
* Universe::narrow_oop_shift() : 0
(なお 1ページ分だけ引いているのは, そのページを implicit null check 用に使いたいため (?)#TODO)
---------------------------------------- -}
#ifdef _LP64
if (UseCompressedOops) {
{- -------------------------------------------
(1)
---------------------------------------- -}
// Subtract a page because something can get allocated at heap base.
// This also makes implicit null checking work, because the
// memory+1 page below heap_base needs to cause a signal.
// See needs_explicit_null_check.
// Only set the heap base for compressed oops because it indicates
// compressed oops for pstack code.
{- -------------------------------------------
(1.1) (変数宣言など)
---------------------------------------- -}
bool verbose = PrintCompressedOopsMode || (PrintMiscellaneous && Verbose);
{- -------------------------------------------
(1.1) (トレース出力)
---------------------------------------- -}
if (verbose) {
tty->cr();
tty->print("heap address: " PTR_FORMAT ", size: " SIZE_FORMAT " MB",
Universe::heap()->base(), Universe::heap()->reserved_region().byte_size()/M);
}
{- -------------------------------------------
(1.1) Universe::narrow_oop_base() と Universe::narrow_oop_shift() の値を決定する.
(なお, 64bit Windows では,
Universe::narrow_oop_base() が 0 になるケースについては,
Universe::_narrow_oop._use_implicit_null_checks が false になっていれば true に戻しておく.
(See: Arguments::set_ergonomics_flags()))
---------------------------------------- -}
if ((uint64_t)Universe::heap()->reserved_region().end() > OopEncodingHeapMax) {
// Can't reserve heap below 32Gb.
Universe::set_narrow_oop_base(Universe::heap()->base() - os::vm_page_size());
Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes);
if (verbose) {
tty->print(", Compressed Oops with base: "PTR_FORMAT, Universe::narrow_oop_base());
}
} else {
Universe::set_narrow_oop_base(0);
if (verbose) {
tty->print(", zero based Compressed Oops");
}
#ifdef _WIN64
if (!Universe::narrow_oop_use_implicit_null_checks()) {
// Don't need guard page for implicit checks in indexed addressing
// mode with zero based Compressed Oops.
Universe::set_narrow_oop_use_implicit_null_checks(true);
}
#endif // _WIN64
if((uint64_t)Universe::heap()->reserved_region().end() > NarrowOopHeapMax) {
// Can't reserve heap below 4Gb.
Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes);
} else {
Universe::set_narrow_oop_shift(0);
if (verbose) {
tty->print(", 32-bits Oops");
}
}
}
{- -------------------------------------------
(1.1) (トレース出力)
---------------------------------------- -}
if (verbose) {
tty->cr();
tty->cr();
}
}
{- -------------------------------------------
(1.1) (assert)
---------------------------------------- -}
assert(Universe::narrow_oop_base() == (Universe::heap()->base() - os::vm_page_size()) ||
Universe::narrow_oop_base() == NULL, "invalid value");
assert(Universe::narrow_oop_shift() == LogMinObjAlignmentInBytes ||
Universe::narrow_oop_shift() == 0, "invalid value");
#endif
{- -------------------------------------------
(1) もし UseTLAB オプションが指定されていれば,
ThreadLocalAllocBuffer::startup_initialization() で ThreadLocalAllocBuffer の初期化を行う.
---------------------------------------- -}
// We will never reach the CATCH below since Exceptions::_throw will cause
// the VM to exit if an exception is thrown during initialization
if (UseTLAB) {
assert(Universe::heap()->supports_tlab_allocation(),
"Should support thread-local allocation buffers");
ThreadLocalAllocBuffer::startup_initialization();
}
{- -------------------------------------------
(1) リターン
---------------------------------------- -}
return JNI_OK;
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.