Top


定義場所(file name)

hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp

名前(function name)

HeapWord* CollectedHeap::common_mem_allocate_noinit(size_t size, bool is_noref, TRAPS) {

本体部(body)

  {- -------------------------------------------
  (1) (デバッグ用の処理) (CHECK_UNHANDLED_OOPS_ONLY 時にのみ実行) (See: UnhandledOops)
      unhandled oop をクリアする (? #TODO)
      ---------------------------------------- -}

      // Clear unhandled oops for memory allocation.  Memory allocation might
      // not take out a lock if from tlab, so clear here.
      CHECK_UNHANDLED_OOPS_ONLY(THREAD->clear_unhandled_oops();)

  {- -------------------------------------------
  (1) もし例外が発生していたらここでリターン.
      ---------------------------------------- -}

      if (HAS_PENDING_EXCEPTION) {
        NOT_PRODUCT(guarantee(false, "Should not allocate with exception pending"));
        return NULL;  // caller does a CHECK_0 too
      }

  {- -------------------------------------------
  (1) (UseTLAB オプションが指定されていれば) まず CollectedHeap::allocate_from_tlab() で TLAB からの確保を試みる.
      確保できたらここでリターン.
      ---------------------------------------- -}

      // We may want to update this, is_noref objects might not be allocated in TLABs.
      HeapWord* result = NULL;
      if (UseTLAB) {
        result = CollectedHeap::allocate_from_tlab(THREAD, size);
        if (result != NULL) {
          assert(!HAS_PENDING_EXCEPTION,
                 "Unexpected exception, will result in uninitialized storage");
          return result;
        }
      }

  {- -------------------------------------------
  (1) Universe::heap() で使用する GC アルゴリズムに対応した CollectedHeap オブジェクトを取得し, 
      その CollectedHeap::mem_allocate() メソッドでメモリ確保を試みる.
       (実際にはこのメソッドはそれぞれのサブクラスでオーバーライドされており, 各 GC アルゴリズムに対応した確保処理が行われる)

      確保できたらここでリターン.

      (なお確保できた場合には, Thread::incr_allocated_bytes() で統計情報の更新処理も行っている 
       (See: [here](no2114Q4Z.html) for details))
      ---------------------------------------- -}

      bool gc_overhead_limit_was_exceeded = false;
      result = Universe::heap()->mem_allocate(size,
                                              is_noref,
                                              false,
                                              &gc_overhead_limit_was_exceeded);
      if (result != NULL) {
        NOT_PRODUCT(Universe::heap()->
          check_for_non_bad_heap_word_value(result, size));
        assert(!HAS_PENDING_EXCEPTION,
               "Unexpected exception, will result in uninitialized storage");
        THREAD->incr_allocated_bytes(size * HeapWordSize);
        return result;
      }


  {- -------------------------------------------
  (1) 確保に失敗した場合は, OutOfMemoryError を THROW する.
      (なお THROW の前に, report_java_out_of_memory() や JvmtiExport::post_resource_exhausted() で 
       OutOfMemory になったことの通知処理も行っている)

      (なお, 以下の処理では gc_overhead_limit_was_exceeded の値に応じて処理を分岐している 
       (gc_overhead_limit_was_exceeded の意味に付いては上記参照).
       といってもどちらのパスも処理自体はほぼ同じで, エラーメッセージの内容等が微妙に違う程度(?)
      ---------------------------------------- -}

      if (!gc_overhead_limit_was_exceeded) {

    {- -------------------------------------------
  (1.1) report_java_out_of_memory() で 
        -XX:+HeapDumpOnOutOfMemoryError オプションや -XX:OnOutOfMemoryError オプションの処理を行う.
        ---------------------------------------- -}

        // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support
        report_java_out_of_memory("Java heap space");

    {- -------------------------------------------
  (1.1) (JVMTI のフック点)
        ---------------------------------------- -}

        if (JvmtiExport::should_post_resource_exhausted()) {
          JvmtiExport::post_resource_exhausted(
            JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | JVMTI_RESOURCE_EXHAUSTED_JAVA_HEAP,
            "Java heap space");
        }

    {- -------------------------------------------
  (1.1) OutOfMemoryError を送出
        ---------------------------------------- -}

        THROW_OOP_0(Universe::out_of_memory_error_java_heap());
      } else {

    {- -------------------------------------------
  (1.1) report_java_out_of_memory() で 
        -XX:+HeapDumpOnOutOfMemoryError オプションや -XX:OnOutOfMemoryError オプションの処理を行う.
        ---------------------------------------- -}

        // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support
        report_java_out_of_memory("GC overhead limit exceeded");

    {- -------------------------------------------
  (1.1) (JVMTI のフック点)
        ---------------------------------------- -}

        if (JvmtiExport::should_post_resource_exhausted()) {
          JvmtiExport::post_resource_exhausted(
            JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | JVMTI_RESOURCE_EXHAUSTED_JAVA_HEAP,
            "GC overhead limit exceeded");
        }

    {- -------------------------------------------
  (1.1) OutOfMemoryError を送出
        ---------------------------------------- -}

        THROW_OOP_0(Universe::out_of_memory_error_gc_overhead_limit());
      }
    }

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