hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
bool G1CollectedHeap::expand(size_t expand_bytes) {
{- -------------------------------------------
(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.