Up Top

Memory allocation (& GC 処理) : メモリの確保処理 (GC 処理) : slow-path の処理 (2)


概要(Summary)

slow-path の処理は, 以下のどれかのメソッドを経由し, 最終的に CollectedHeap::common_mem_allocate_init() にたどり着く. その中で確保処理が行われる.

CollectedHeap::common_mem_allocate_init() での確保処理は, 大別すると以下の2つからなる.

オブジェクトの確保処理(new バイトコード命令の処理)の slow-path

  1. 各種の Runtime クラスから instanceKlass::allocate_instance() が呼び出される.
  2. そこから, CollectedHeap::obj_allocate() が呼び出される.
  3. 最終的に CollectedHeap::common_mem_allocate_init() が呼び出される.

配列の確保処理(newarray バイトコード命令の処理)の slow-path

  1. 各種の Runtime クラスから oopFactory::new_typeArray() が呼び出される.
  2. そこから, CollectedHeap::array_allocate() または CollectedHeap::large_typearray_allocate() が呼び出される.
  3. 最終的に CollectedHeap::common_mem_allocate_init() が呼び出される.

オブジェクト配列の確保処理(anewarray バイトコード命令の処理)の slow-path

  1. 各種の Runtime クラスから oopFactory::new_objArray() が呼び出される.
  2. そこから, CollectedHeap::array_allocate() が呼び出される.
  3. 最終的に CollectedHeap::common_mem_allocate_init() が呼び出される.

多次元配列の確保処理(multianewarray バイトコード命令の処理)の slow-path

  1. 各種の Runtime クラスから arrayKlass::multi_allocate() が呼び出される.

(正確には arrayKlass::multi_allocate() 自体は空のメソッドで, 実際にはそれをサブクラスがオーバーライドしたものが呼び出される. より具体的には, objArrayKlass::multi_allocate() または typeArrayKlass::multi_allocate() が呼び出される)

(多次元配列は, 最後の一段以外は参照の配列なので, objArrayKlass::multi_allocate() 内部で必要な次元数分だけ objArrayKlass::allocate() による確保が行われる. 正確には, objArrayKlass::multi_allocate() の再起呼び出しで確保が行われる. プリミティブ型の場合は最後の一段だけは typeArrayKlass::multi_allocate() になるが, typeArrayKlass::multi_allocate() も中身は typeArrayKlass::allocate() を呼ぶだけ)

  1. そこから, CollectedHeap::array_allocate() または CollectedHeap::large_typearray_allocate() が呼び出される.
  2. 最終的に CollectedHeap::common_mem_allocate_init() が呼び出される.

処理の流れ (概要)(Execution Flows : Summary)

オブジェクトの確保処理(new バイトコード命令の処理)の slow-path

-> instanceKlass::allocate_instance()
   -> CollectedHeap::obj_allocate()
      -> CollectedHeap::common_mem_allocate_init()
         -> CollectedHeap::common_mem_allocate_noinit()
            -> (1) 以下の2つ(UseTLAB オプションが指定されてなければ1つ)の方法でメモリの確保を試みる.

                   -> CollectedHeap::allocate_from_tlab()      (<= UseTLAB オプションが指定されている場合にのみ実行)
                      -> ThreadLocalAllocBuffer::allocate()        (<= 現在の TLAB からメモリを確保)
                      -> CollectedHeap::allocate_from_tlab_slow()  (<= もし現在の TLAB で足りなければ, これで新しい TLAB を確保)
                         -> ThreadLocalAllocBuffer::compute_size()
                         -> CollectedHeap::allocate_new_tlab()     (<= 実際にはこのメソッドの中身は各サブクラスでオーバーライドされている)
                            -> (See: here, here, here and here for details)
                   -> CollectedHeap::mem_allocate()            (<= 実際にはこのメソッドの中身は各サブクラスでオーバーライドされている)
                      -> (See: here, here, here and here for details)
        
               (1) 以上の二つで確保できなければ OutOfMemoryError を送出する.
                   (なお, -XX:+HeapDumpOnOutOfMemoryError オプションや 
                   -XX:OnOutOfMemoryError オプション, 
                   および JVMTI の ResourceExhausted の処理も行う) 

                   -> report_java_out_of_memory()
                   -> JvmtiExport::post_resource_exhausted()
                   -> THROW_OOP_0()

         -> CollectedHeap::init_obj() で, 確保したメモリのヘッダー部以外の領域を 0 クリアする
      -> CollectedHeap::post_allocation_setup_obj() でヘッダー部を初期化する. (また, ここが JVMTI や DTrace, JMM のフック点でもある)

配列の確保処理(newarray バイトコード命令の処理)の slow-path

-> oopFactory::new_typeArray()
   -> typeArrayKlass::allocate()
      -> CollectedHeap::array_allocate()  または  CollectedHeap::large_typearray_allocate()
         -> CollectedHeap::common_mem_allocate_init()
            -> 同上
         -> CollectedHeap::post_allocation_setup_array() でヘッダー部を初期化する. (また, ここが JVMTI や DTrace, JMM のフック点でもある)

オブジェクト配列の確保処理(anewarray バイトコード命令の処理)の slow-path

-> oopFactory::new_objArray()
   -> arrayKlass::allocate_arrayArray()  または  instanceKlass::allocate_objArray()
      -> CollectedHeap::array_allocate()
         -> 同上

多次元配列の確保処理(multianewarray バイトコード命令の処理)の slow-path

-> objArrayKlass::multi_allocate()  or  typeArrayKlass::multi_allocate()
   -> objArrayKlass::allocate()
      -> CollectedHeap::array_allocate()
         -> 同上
   -> typeArrayKlass::allocate()
      -> 同上

処理の流れ (詳細)(Execution Flows : Details)

instanceKlass::allocate_instance()

See: here for details

instanceKlass::register_finalizer()

See: here for details

java.lang.ref.Finalizer.register()

See: here for details

CollectedHeap::obj_allocate()

See: here for details

CollectedHeap::common_mem_allocate_init()

See: here for details

CollectedHeap::common_mem_allocate_noinit()

See: here for details

CollectedHeap::allocate_from_tlab()

See: here for details

ThreadLocalAllocBuffer::allocate()

See: here for details

CollectedHeap::allocate_from_tlab_slow()

See: here for details

report_java_out_of_memory()

See: here for details

VMError::report_java_out_of_memory()

See: here for details

VM_ReportJavaOutOfMemory::doit()

See: here for details

JvmtiExport::post_resource_exhausted()

(#Under Construction)

CollectedHeap::init_obj()

See: here for details

CollectedHeap::post_allocation_setup_obj()

See: here for details

oopFactory::new_typeArray()

See: here for details

typeArrayKlass::allocate()

See: here for details

CollectedHeap::array_allocate()

See: here for details

CollectedHeap::large_typearray_allocate()

See: here for details

CollectedHeap::post_allocation_setup_array()

See: here for details

CollectedHeap::post_allocation_setup_common()

See: here for details

CollectedHeap::post_allocation_setup_no_klass_install()

See: here for details

CollectedHeap::post_allocation_install_obj_klass()

See: here for details

oopFactory::new_objArray()

See: here for details

arrayKlass::allocate_arrayArray()

See: here for details

instanceKlass::allocate_objArray()

See: here for details

objArrayKlass::multi_allocate()

See: here for details

typeArrayKlass::multi_allocate()

See: here for details

objArrayKlass::allocate()

See: here for details

ThreadLocalAllocBuffer::fill()

See: here for details

ThreadLocalAllocBuffer::record_slow_allocation()

See: here for details

ThreadLocalAllocBuffer::compute_size()

See: here for details

ThreadLocalAllocBuffer::clear_before_allocation()

See: here for details

ThreadLocalAllocBuffer::make_parsable()

See: here for details


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