Top


定義場所(file name)

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

名前(function name)

jint Universe::initialize_heap() {

本体部(body)

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