hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
HeapWord* allocate_slow(GCAllocPurpose purpose, size_t word_sz) {
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
HeapWord* obj = NULL;
size_t gclab_word_size = _g1h->desired_plab_sz(purpose);
{- -------------------------------------------
(1) (以下の処理はバッファの残り量が十分かどうかに応じて 2通り.
ここに来ていると言うことは, fast path の確保処理は失敗したと言うこと.
失敗した理由としては, バッファの残り量が少な過ぎるケースと, 確保要求量が大き過ぎるケースが考えられる.
バッファの残り量が少な過ぎる場合は, 新しいバッファを確保する.
確保要求量が大き過ぎる場合は, (現在のバッファはまだ破棄するにはもったいないので)
G1CollectedHeap 中から直接メモリ領域を確保する.)
---------------------------------------- -}
{- -------------------------------------------
(1) (以下は, 確保要求量は大きくなかった場合 (= バッファの残り量が少な過ぎる場合).
より具体的に言うと, 確保要求量(word_sz)が
デフォルトの plab サイズ (= G1CollectedHeap::desired_plab_sz() の返値) の
ParallelGCBufferWastePct% 未満の場合.
なお, word_sz を 100倍しているのは ParallelGCBufferWastePct の単位が % であるため.)
---------------------------------------- -}
if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) {
{- -------------------------------------------
(1.1) まず G1ParGCAllocBuffer::retire() を呼んで,
purpose 引数に対応する G1ParGCAllocBuffer オブジェクトのバッファを無効にする.
次に G1CollectedHeap::par_allocate_during_gc() を呼んで新しいバッファを確保し,
G1ParGCAllocBuffer::set_buf() でその G1ParGCAllocBuffer にセットする.
最後に, ParGCAllocBuffer::allocate() を呼んで
word_sz 引数で指定された量のメモリ領域を
新しいバッファから確保する.
(なお, G1ParGCAllocBuffer のバッファを無効にする直前に
G1ParScanThreadState::add_to_alloc_buffer_waste() を呼び出し,
無駄になる領域量の記録も行っている)
---------------------------------------- -}
G1ParGCAllocBuffer* alloc_buf = alloc_buffer(purpose);
assert(gclab_word_size == alloc_buf->word_sz(),
"dynamic resizing is not supported");
add_to_alloc_buffer_waste(alloc_buf->words_remaining());
alloc_buf->retire(false, false);
HeapWord* buf = _g1h->par_allocate_during_gc(purpose, gclab_word_size);
if (buf == NULL) return NULL; // Let caller handle allocation failure.
// Otherwise.
alloc_buf->set_buf(buf);
obj = alloc_buf->allocate(word_sz);
assert(obj != NULL, "buffer was definitely big enough...");
{- -------------------------------------------
(1) (以下は, 確保要求量が大き過ぎる場合)
---------------------------------------- -}
} else {
{- -------------------------------------------
(1.1) G1CollectedHeap::par_allocate_during_gc() を呼んで,
word_sz 引数で指定された量のメモリ領域を確保する.
---------------------------------------- -}
obj = _g1h->par_allocate_during_gc(purpose, word_sz);
}
{- -------------------------------------------
(1) 確保したメモリ領域をリターン
---------------------------------------- -}
return obj;
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.