hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
HeapWord*
G1CollectedHeap::satisfy_failed_allocation(size_t word_size,
bool* succeeded) {
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
assert_at_safepoint(true /* should_be_vm_thread */);
{- -------------------------------------------
(1) succeeded 引数が指す箇所を true で初期化しておく.
---------------------------------------- -}
*succeeded = true;
{- -------------------------------------------
(1) まず G1CollectedHeap::attempt_allocation_at_safepoint() で確保を試みる.
確保に成功したら, ここでリターン.
---------------------------------------- -}
// Let's attempt the allocation first.
HeapWord* result =
attempt_allocation_at_safepoint(word_size,
false /* expect_null_mutator_alloc_region */);
if (result != NULL) {
assert(*succeeded, "sanity");
return result;
}
{- -------------------------------------------
(1) まず G1CollectedHeap::expand_and_allocate() で確保を試みる.
確保に成功したら, ここでリターン.
---------------------------------------- -}
// In a G1 heap, we're supposed to keep allocation from failing by
// incremental pauses. Therefore, at least for now, we'll favor
// expansion over collection. (This might change in the future if we can
// do something smarter than full collection to satisfy a failed alloc.)
result = expand_and_allocate(word_size);
if (result != NULL) {
assert(*succeeded, "sanity");
return result;
}
{- -------------------------------------------
(1) G1CollectedHeap::do_collection() を呼んで, Full GC を実行する.
Full GC が失敗したら, succeeded 引数が指す箇所を false に変更した後, ここで NULL をリターン.
---------------------------------------- -}
// Expansion didn't work, we'll try to do a Full GC.
bool gc_succeeded = do_collection(false, /* explicit_gc */
false, /* clear_all_soft_refs */
word_size);
if (!gc_succeeded) {
*succeeded = false;
return NULL;
}
{- -------------------------------------------
(1) もう一度 G1CollectedHeap::attempt_allocation_at_safepoint() で確保を試みる.
確保に成功したら, ここでリターン.
---------------------------------------- -}
// Retry the allocation
result = attempt_allocation_at_safepoint(word_size,
true /* expect_null_mutator_alloc_region */);
if (result != NULL) {
assert(*succeeded, "sanity");
return result;
}
{- -------------------------------------------
(1) G1CollectedHeap::do_collection() を呼んで, もう一度 Full GC を実行する.
(今度は soft reference は全部消すことにする)
Full GC が失敗したら, succeeded 引数が指す箇所を false に変更した後, ここで NULL をリターン.
---------------------------------------- -}
// Then, try a Full GC that will collect all soft references.
gc_succeeded = do_collection(false, /* explicit_gc */
true, /* clear_all_soft_refs */
word_size);
if (!gc_succeeded) {
*succeeded = false;
return NULL;
}
{- -------------------------------------------
(1) もう一度 G1CollectedHeap::attempt_allocation_at_safepoint() で確保を試みる.
確保に成功したら, ここでリターン.
---------------------------------------- -}
// Retry the allocation once more
result = attempt_allocation_at_safepoint(word_size,
true /* expect_null_mutator_alloc_region */);
if (result != NULL) {
assert(*succeeded, "sanity");
return result;
}
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
assert(!collector_policy()->should_clear_all_soft_refs(),
"Flag should have been handled and cleared prior to this point");
// What else? We might try synchronous finalization later. If the total
// space available is large enough for the allocation, then a more
// complete compaction phase than we've tried so far might be
// appropriate.
assert(*succeeded, "sanity");
{- -------------------------------------------
(1) NULL をリターン.
---------------------------------------- -}
return NULL;
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.