hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp
HeapWord* CollectedHeap::common_mem_allocate_noinit(size_t size, bool is_noref, TRAPS) {
{- -------------------------------------------
(1) (デバッグ用の処理) (CHECK_UNHANDLED_OOPS_ONLY 時にのみ実行) (See: UnhandledOops)
unhandled oop をクリアする (? #TODO)
---------------------------------------- -}
// Clear unhandled oops for memory allocation. Memory allocation might
// not take out a lock if from tlab, so clear here.
CHECK_UNHANDLED_OOPS_ONLY(THREAD->clear_unhandled_oops();)
{- -------------------------------------------
(1) もし例外が発生していたらここでリターン.
---------------------------------------- -}
if (HAS_PENDING_EXCEPTION) {
NOT_PRODUCT(guarantee(false, "Should not allocate with exception pending"));
return NULL; // caller does a CHECK_0 too
}
{- -------------------------------------------
(1) (UseTLAB オプションが指定されていれば) まず CollectedHeap::allocate_from_tlab() で TLAB からの確保を試みる.
確保できたらここでリターン.
---------------------------------------- -}
// We may want to update this, is_noref objects might not be allocated in TLABs.
HeapWord* result = NULL;
if (UseTLAB) {
result = CollectedHeap::allocate_from_tlab(THREAD, size);
if (result != NULL) {
assert(!HAS_PENDING_EXCEPTION,
"Unexpected exception, will result in uninitialized storage");
return result;
}
}
{- -------------------------------------------
(1) Universe::heap() で使用する GC アルゴリズムに対応した CollectedHeap オブジェクトを取得し,
その CollectedHeap::mem_allocate() メソッドでメモリ確保を試みる.
(実際にはこのメソッドはそれぞれのサブクラスでオーバーライドされており, 各 GC アルゴリズムに対応した確保処理が行われる)
確保できたらここでリターン.
(なお確保できた場合には, Thread::incr_allocated_bytes() で統計情報の更新処理も行っている
(See: [here](no2114Q4Z.html) for details))
---------------------------------------- -}
bool gc_overhead_limit_was_exceeded = false;
result = Universe::heap()->mem_allocate(size,
is_noref,
false,
&gc_overhead_limit_was_exceeded);
if (result != NULL) {
NOT_PRODUCT(Universe::heap()->
check_for_non_bad_heap_word_value(result, size));
assert(!HAS_PENDING_EXCEPTION,
"Unexpected exception, will result in uninitialized storage");
THREAD->incr_allocated_bytes(size * HeapWordSize);
return result;
}
{- -------------------------------------------
(1) 確保に失敗した場合は, OutOfMemoryError を THROW する.
(なお THROW の前に, report_java_out_of_memory() や JvmtiExport::post_resource_exhausted() で
OutOfMemory になったことの通知処理も行っている)
(なお, 以下の処理では gc_overhead_limit_was_exceeded の値に応じて処理を分岐している
(gc_overhead_limit_was_exceeded の意味に付いては上記参照).
といってもどちらのパスも処理自体はほぼ同じで, エラーメッセージの内容等が微妙に違う程度(?)
---------------------------------------- -}
if (!gc_overhead_limit_was_exceeded) {
{- -------------------------------------------
(1.1) report_java_out_of_memory() で
-XX:+HeapDumpOnOutOfMemoryError オプションや -XX:OnOutOfMemoryError オプションの処理を行う.
---------------------------------------- -}
// -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support
report_java_out_of_memory("Java heap space");
{- -------------------------------------------
(1.1) (JVMTI のフック点)
---------------------------------------- -}
if (JvmtiExport::should_post_resource_exhausted()) {
JvmtiExport::post_resource_exhausted(
JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | JVMTI_RESOURCE_EXHAUSTED_JAVA_HEAP,
"Java heap space");
}
{- -------------------------------------------
(1.1) OutOfMemoryError を送出
---------------------------------------- -}
THROW_OOP_0(Universe::out_of_memory_error_java_heap());
} else {
{- -------------------------------------------
(1.1) report_java_out_of_memory() で
-XX:+HeapDumpOnOutOfMemoryError オプションや -XX:OnOutOfMemoryError オプションの処理を行う.
---------------------------------------- -}
// -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support
report_java_out_of_memory("GC overhead limit exceeded");
{- -------------------------------------------
(1.1) (JVMTI のフック点)
---------------------------------------- -}
if (JvmtiExport::should_post_resource_exhausted()) {
JvmtiExport::post_resource_exhausted(
JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | JVMTI_RESOURCE_EXHAUSTED_JAVA_HEAP,
"GC overhead limit exceeded");
}
{- -------------------------------------------
(1.1) OutOfMemoryError を送出
---------------------------------------- -}
THROW_OOP_0(Universe::out_of_memory_error_gc_overhead_limit());
}
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.