hotspot/src/share/vm/memory/genCollectedHeap.cpp
jint GenCollectedHeap::initialize() {
{- -------------------------------------------
(1) CollectedHeap::pre_initialize() を呼んで, 初期化の前準備を行っておく.
(現状では C2 用のフィールドの初期化があるだけ)
---------------------------------------- -}
CollectedHeap::pre_initialize();
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
int i;
{- -------------------------------------------
(1) _n_gens フィールドを Generation の個数に初期化
---------------------------------------- -}
_n_gens = gen_policy()->number_of_generations();
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
// While there are no constraints in the GC code that HeapWordSize
// be any particular value, there are multiple other areas in the
// system which believe this to be true (e.g. oop->object_size in some
// cases incorrectly returns the size in wordSize units rather than
// HeapWordSize).
guarantee(HeapWordSize == wordSize, "HeapWordSize must equal wordSize");
{- -------------------------------------------
(1) 各 Generation は Generation::GenGrain で align させることとする (なんで?? #TODO)
---------------------------------------- -}
// The heap must be at least as aligned as generations.
size_t alignment = Generation::GenGrain;
_gen_specs = gen_policy()->generations();
PermanentGenerationSpec *perm_gen_spec =
collector_policy()->permanent_generation();
// Make sure the sizes are all aligned.
for (i = 0; i < _n_gens; i++) {
_gen_specs[i]->align(alignment);
}
perm_gen_spec->align(alignment);
{- -------------------------------------------
(1) DumpSharedSpaces オプションが指定されている場合は,
os::reserve_memory() で
SharedDummyBlockSize 分のメモリを reserve しておく.
---------------------------------------- -}
// If we are dumping the heap, then allocate a wasted block of address
// space in order to push the heap to a lower address. This extra
// address range allows for other (or larger) libraries to be loaded
// without them occupying the space required for the shared spaces.
if (DumpSharedSpaces) {
uintx reserved = 0;
uintx block_size = 64*1024*1024;
while (reserved < SharedDummyBlockSize) {
char* dummy = os::reserve_memory(block_size);
reserved += block_size;
}
}
{- -------------------------------------------
(1) GenCollectedHeap::allocate() でヒープ領域をメモリ空間上に確保する.
(なお, ここではまず Young, Old, Perm の全世代分をまとめて1つの連続領域として確保する.
各 Generation 毎に分ける作業は後で行う.)
---------------------------------------- -}
// Allocate space for the heap.
char* heap_address;
size_t total_reserved = 0;
int n_covered_regions = 0;
ReservedSpace heap_rs(0);
heap_address = allocate(alignment, perm_gen_spec, &total_reserved,
&n_covered_regions, &heap_rs);
{- -------------------------------------------
(1) UseSharedSpaces オプションが指定されている場合, ... #TODO
---------------------------------------- -}
if (UseSharedSpaces) {
if (!heap_rs.is_reserved() || heap_address != heap_rs.base()) {
if (heap_rs.is_reserved()) {
heap_rs.release();
}
FileMapInfo* mapinfo = FileMapInfo::current_info();
mapinfo->fail_continue("Unable to reserve shared region.");
allocate(alignment, perm_gen_spec, &total_reserved, &n_covered_regions,
&heap_rs);
}
}
{- -------------------------------------------
(1) もしヒープ領域の確保に失敗していれば, ここでリターン.
---------------------------------------- -}
if (!heap_rs.is_reserved()) {
vm_shutdown_during_initialization(
"Could not reserve enough space for object heap");
return JNI_ENOMEM;
}
{- -------------------------------------------
(1) 確保したヒープ領域を表す MemRegion オブジェクトを生成し,
自分の CollectedHeap::_reserved フィールドに格納.
その後, MemRegion 内のフィールドを微調整.
---------------------------------------- -}
_reserved = MemRegion((HeapWord*)heap_rs.base(),
(HeapWord*)(heap_rs.base() + heap_rs.size()));
// It is important to do this in a way such that concurrent readers can't
// temporarily think somethings in the heap. (Seen this happen in asserts.)
_reserved.set_word_size(0);
_reserved.set_start((HeapWord*)heap_rs.base());
size_t actual_heap_size = heap_rs.size() - perm_gen_spec->misc_data_size()
- perm_gen_spec->misc_code_size();
_reserved.set_end((HeapWord*)(heap_rs.base() + actual_heap_size));
{- -------------------------------------------
(1) 生成した MemRegion を元にして Remembered Set を生成し,
自分の SharedHeap::_rem_set フィールドに格納.
また, SharedHeap::set_barrier_set() を呼んで,
生成した Remembered Set 中の Barrier Set を
自分の CollectedHeap::_barrier_set フィールドに格納.
<= SharedHeap::set_barrier_set() では, oopDesc のフィールドにも格納しているようだが... #TODO
---------------------------------------- -}
_rem_set = collector_policy()->create_rem_set(_reserved, n_covered_regions);
set_barrier_set(rem_set()->bs());
{- -------------------------------------------
(1) static 変数の _gch に自分自身をセットしておく.
---------------------------------------- -}
_gch = this;
{- -------------------------------------------
(1) 上で1つの連続領域として確保したヒープ空間を, 各世代に(それぞれの max_size()に応じて)割り振る.
(各世代毎の ReservedSpace を作成し, それぞれに適切な GenerationSpec::init() を呼び出すことで,
対応する Generation オブジェクトを作成する)
---------------------------------------- -}
for (i = 0; i < _n_gens; i++) {
ReservedSpace this_rs = heap_rs.first_part(_gen_specs[i]->max_size(),
UseSharedSpaces, UseSharedSpaces);
_gens[i] = _gen_specs[i]->init(this_rs, i, rem_set());
heap_rs = heap_rs.last_part(_gen_specs[i]->max_size());
}
{- -------------------------------------------
(1) Perm 領域についても, PermanentGenerationSpec::init() を呼び出すことで対応する PermGen オブジェクトを生成する.
---------------------------------------- -}
_perm_gen = perm_gen_spec->init(heap_rs, PermSize, rem_set());
{- -------------------------------------------
(1) ?? #TODO
---------------------------------------- -}
clear_incremental_collection_failed();
{- -------------------------------------------
(1) もし CMS であれば, GC 用のスレッドを作成する.
---------------------------------------- -}
#ifndef SERIALGC
// If we are running CMS, create the collector responsible
// for collecting the CMS generations.
if (collector_policy()->is_concurrent_mark_sweep_policy()) {
bool success = create_cms_collector();
if (!success) return JNI_ENOMEM;
}
#endif // SERIALGC
{- -------------------------------------------
(1) リターン
---------------------------------------- -}
return JNI_OK;
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.