Up Top

Memory allocation (& GC 処理) : メモリの確保処理 (GC 処理) : slow-path の処理 (3) TLAB の確保処理 : G1collectedheap の場合


概要(Summary)

TLAB の確保処理により CollectedHeap::allocate_new_tlab() が呼び出される (See: here for details). G1collectedheap は CollectedHeap::allocate_new_tlab() をオーバーライドしているので, 実際に呼び出されるのは G1collectedheap::allocate_new_tlab() になる.

G1collectedheap::allocate_new_tlab() からは, メモリ確保のために2つの方法が試みられる.

  1. まず G1AllocRegion::attempt_allocation() での確保が試される.

この場合, 最終的には ContiguousSpace::par_allocate() 又は ContiguousSpace::allocate() が呼び出されて確保処理が行われる.

  1. 駄目なら G1CollectedHeap::attempt_allocation_slow() での確保が試される.

この場合, 最終的には G1CollectedHeap::new_region() (及び G1AllocRegion::allocate()) が呼び出されて確保処理が行われる.

備考(Notes)

確保に使用する HeapRegion は G1AllocRegion::_alloc_region フィールドに格納されている (See: G1AllocRegion).

そして, G1AllocRegion::alloc_region が一杯になった場合は G1AllocRegion::new_alloc_regionand_allocate() で新しい HeapRegion がセットされる.

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

G1CollectedHeap::allocate_new_tlab()
-> G1CollectedHeap::attempt_allocation()
   -> (1) まず G1AllocRegion::attempt_allocation() での確保が試みられる.
          -> G1AllocRegion::attempt_allocation()
             -> G1AllocRegion::par_allocate()
                (以下のどちらかで確保を行う)
                -> HeapRegion::par_allocate_no_bot_updates()
                   -> ContiguousSpace::par_allocate()
                -> G1OffsetTableContigSpace::par_allocate()
                   -> ContiguousSpace::allocate()

      (1) 駄目なら G1CollectedHeap::attempt_allocation_slow() での確保が試みられる.
          -> G1CollectedHeap::attempt_allocation_slow()
             -> G1AllocRegion::attempt_allocation_locked()
                -> G1AllocRegion::attempt_allocation()  (<= ロック待ちの間に他のスレッドが allocate を行ったかもしれないので, もう一度 G1AllocRegion::attempt_allocation() をためす. 成功すればここでリターン)
                -> G1AllocRegion::retire() (<= 一杯になった HeapRegion を incremental collection set に追加する処理を行う)
                   -> G1AllocRegion::fill_up_remaining_space()
                   -> MutatorAllocRegion::retire_region()
                      -> G1CollectedHeap::retire_mutator_alloc_region()
                         -> G1CollectorPolicy::add_region_to_incremental_cset_lhs()
                            -> G1CollectorPolicy::add_region_to_incremental_cset_common()
                -> G1AllocRegion::new_alloc_region_and_allocate() (<= G1AllocRegion 用の新しい HeapRegion の確保を試みる)
                   -> MutatorAllocRegion::allocate_new_region()
                      -> G1CollectedHeap::new_mutator_alloc_region()
                         -> G1CollectorPolicy::is_young_list_full()
                         -> G1CollectedHeap::new_region()
                         (確保が成功したら以下の処理を行う)
                         -> G1CollectedHeap::set_region_short_lived_locked()
                            -> YoungList::push_region()
                            -> G1CollectorPolicy::set_region_short_lived()
             -> G1AllocRegion::attempt_allocation_force()  (<= もし GC_locker が有効になっているために GC できない状況であれば, これでメモリ確保を試みる)
                -> G1AllocRegion::new_alloc_region_and_allocate()
                   -> (同上)
             -> G1CollectedHeap::do_collection_pause()
                -> (See: here for details)

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

G1CollectedHeap::allocate_new_tlab()

See: here for details

G1CollectedHeap::attempt_allocation()

See: here for details

G1AllocRegion::attempt_allocation()

See: here for details

G1AllocRegion::par_allocate()

See: here for details

備考(Notes)

なお, G1AllocRegion::par_allocate() の引数の bot_updates は, block offset table の更新を必要とするかどうか? を示す模様. そして young generation だと false になる.

(par_allocate_no_bot_updates() 内の assert から判断)

    ((cite: hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp))
      inline HeapWord* par_allocate_no_bot_updates(size_t word_size) {
        assert(is_young(), "we can only skip BOT updates on young regions");

HeapRegion::par_allocate_no_bot_updates()

See: here for details

G1OffsetTableContigSpace::par_allocate()

See: here for details

G1CollectedHeap::attempt_allocation_slow()

See: here for details

G1AllocRegion::attempt_allocation_locked()

See: here for details

G1AllocRegion::retire()

See: here for details

MutatorAllocRegion::retire_region()

See: here for details

G1CollectedHeap::retire_mutator_alloc_region()

See: here for details

G1CollectorPolicy::add_region_to_incremental_cset_lhs()

See: here for details

G1CollectorPolicy::add_region_to_incremental_cset_common()

(#Under Construction)

G1AllocRegion::new_alloc_region_and_allocate()

See: here for details

MutatorAllocRegion::allocate_new_region()

See: here for details

G1CollectedHeap::new_mutator_alloc_region()

See: here for details

G1CollectorPolicy::is_young_list_full()

See: here for details

G1CollectedHeap::new_region()

See: here for details

G1CollectedHeap::set_region_short_lived_locked()

See: here for details

YoungList::push_region()

See: here for details

G1CollectorPolicy::set_region_short_lived()

See: here for details

G1AllocRegion::attempt_allocation_force()

See: here for details


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