Top


定義場所(file name)

hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp

名前(function name)

bool G1CollectedHeap::expand(size_t expand_bytes) {

本体部(body)

  {- -------------------------------------------
  (1) (変数宣言など)
      ---------------------------------------- -}

      size_t old_mem_size = _g1_storage.committed_size();
      size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes);
      aligned_expand_bytes = align_size_up(aligned_expand_bytes,
                                           HeapRegion::GrainBytes);

  {- -------------------------------------------
  (1) (トレース出力)
      ---------------------------------------- -}

      if (Verbose && PrintGC) {
        gclog_or_tty->print("Expanding garbage-first heap from %ldK by %ldK",
                               old_mem_size/K, aligned_expand_bytes/K);
      }

  {- -------------------------------------------
  (1) (変数宣言など)
      ---------------------------------------- -}

      HeapWord* old_end = (HeapWord*)_g1_storage.high();

  {- -------------------------------------------
  (1) VirtualSpace::expand_by() を呼んで, ヒープ領域の拡張を試みる.
      ---------------------------------------- -}

      bool successful = _g1_storage.expand_by(aligned_expand_bytes);

  {- -------------------------------------------
  (1) 拡張が成功した場合は, ...#TODO
      ---------------------------------------- -}

      if (successful) {
        HeapWord* new_end = (HeapWord*)_g1_storage.high();

        // Expand the committed region.
        _g1_committed.set_end(new_end);

        // Tell the cardtable about the expansion.
        Universe::heap()->barrier_set()->resize_covered_region(_g1_committed);

        // And the offset table as well.
        _bot_shared->resize(_g1_committed.word_size());

        expand_bytes = aligned_expand_bytes;
        HeapWord* base = old_end;

        // Create the heap regions for [old_end, new_end)
        while (expand_bytes > 0) {
          HeapWord* high = base + HeapRegion::GrainWords;

          // Create a new HeapRegion.
          MemRegion mr(base, high);
          bool is_zeroed = !_g1_max_committed.contains(base);
          HeapRegion* hr = new HeapRegion(_bot_shared, mr, is_zeroed);

          // Add it to the HeapRegionSeq.
          _hrs->insert(hr);
          _free_list.add_as_tail(hr);

          // And we used up an expansion region to create it.
          _expansion_regions--;

          expand_bytes -= HeapRegion::GrainBytes;
          base += HeapRegion::GrainWords;
        }
        assert(base == new_end, "sanity");

        // Now update max_committed if necessary.
        _g1_max_committed.set_end(MAX2(_g1_max_committed.end(), new_end));

  {- -------------------------------------------
  (1) 拡張が失敗した場合, ...(#TODO) であれば 
      vm_exit_out_of_memory() で強制終了する.
      ---------------------------------------- -}

      } else {
        // The expansion of the virtual storage space was unsuccessful.
        // Let's see if it was because we ran out of swap.
        if (G1ExitOnExpansionFailure &&
            _g1_storage.uncommitted_size() >= aligned_expand_bytes) {
          // We had head room...
          vm_exit_out_of_memory(aligned_expand_bytes, "G1 heap expansion");
        }
      }

  {- -------------------------------------------
  (1) (トレース出力)
      ---------------------------------------- -}

      if (Verbose && PrintGC) {
        size_t new_mem_size = _g1_storage.committed_size();
        gclog_or_tty->print_cr("...%s, expanded to %ldK",
                               (successful ? "Successful" : "Failed"),
                               new_mem_size/K);
      }

  {- -------------------------------------------
  (1) 結果をリターン
      ---------------------------------------- -}

      return successful;
    }

This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.