Top


定義場所(file name)

hotspot/src/share/vm/memory/genCollectedHeap.cpp

名前(function name)

jint GenCollectedHeap::initialize() {

本体部(body)

  {- -------------------------------------------
  (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.