hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
bool G1CollectedHeap::do_collection(bool explicit_gc,
bool clear_all_soft_refs,
size_t word_size) {
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
assert_at_safepoint(true /* should_be_vm_thread */);
{- -------------------------------------------
(1) もし GC_locker によって GC が禁止されていれば, ここでリターン.
---------------------------------------- -}
if (GC_locker::check_active_before_gc()) {
return false;
}
{- -------------------------------------------
(1) (DTrace のフック点) (JVMTI のフック点)
(See: SvcGCMarker)
---------------------------------------- -}
SvcGCMarker sgcm(SvcGCMarker::FULL);
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
ResourceMark rm;
{- -------------------------------------------
(1) (トレース出力)
---------------------------------------- -}
if (PrintHeapAtGC) {
Universe::print_heap_before_gc();
}
{- -------------------------------------------
(1) (verify)
---------------------------------------- -}
verify_region_sets_optional();
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
const bool do_clear_all_soft_refs = clear_all_soft_refs ||
collector_policy()->should_clear_all_soft_refs();
ClearedAllSoftRefs casr(do_clear_all_soft_refs, collector_policy());
{- -------------------------------------------
(1) (変数宣言など) (See: IsGCActiveMark)
---------------------------------------- -}
{
IsGCActiveMark x;
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
// Timing
bool system_gc = (gc_cause() == GCCause::_java_lang_system_gc);
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
assert(!system_gc || explicit_gc, "invariant");
{- -------------------------------------------
(1) (トレース出力)
---------------------------------------- -}
gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
TraceTime t(system_gc ? "Full GC (System.gc())" : "Full GC",
PrintGC, true, gclog_or_tty);
TraceCollectorStats tcs(g1mm()->full_collection_counters());
TraceMemoryManagerStats tms(true /* fullGC */, gc_cause());
{- -------------------------------------------
(1) (変数宣言など)
(処理の開始時間を記録しておく)
---------------------------------------- -}
double start = os::elapsedTime();
{- -------------------------------------------
(1)
---------------------------------------- -}
g1_policy()->record_full_collection_start();
{- -------------------------------------------
(1) G1CollectedHeap::wait_while_free_regions_coming() を呼んで,
Concurrent Mark が見つけた free region があり, しかもまだ処理途中の段階であれば,
それらの処理が終わるまで待機しておく.
---------------------------------------- -}
wait_while_free_regions_coming();
{- -------------------------------------------
(1)
---------------------------------------- -}
append_secondary_free_list_if_not_empty_with_lock();
gc_prologue(true);
{- -------------------------------------------
(1) GC を行うことになったので, CollectedHeap::total_collections() の値を増加させておく.
(See: CollectedHeap::total_collections())
---------------------------------------- -}
increment_total_collections(true /* full gc */);
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
size_t g1h_prev_used = used();
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
assert(used() == recalculate_used(), "Should be equal");
{- -------------------------------------------
(1) (verify)
---------------------------------------- -}
if (VerifyBeforeGC && total_collections() >= VerifyGCStartAt) {
HandleMark hm; // Discard invalid handles created during verification
gclog_or_tty->print(" VerifyBeforeGC:");
prepare_for_verify();
Universe::verify(true);
}
{- -------------------------------------------
(1) #ifdef COMPILER2 の場合には, (これから GC を行うので) DerivedPointerTable の値をリセットしておく.
(See: DerivedPointerTable)
---------------------------------------- -}
COMPILER2_PRESENT(DerivedPointerTable::clear());
{- -------------------------------------------
(1)
---------------------------------------- -}
// We want to discover references, but not process them yet.
// This mode is disabled in
// instanceRefKlass::process_discovered_references if the
// generation does some collection work, or
// instanceRefKlass::enqueue_discovered_references if the
// generation returns without doing any work.
ref_processor()->disable_discovery();
ref_processor()->abandon_partial_discovery();
ref_processor()->verify_no_references_recorded();
// Abandon current iterations of concurrent marking and concurrent
// refinement, if any are in progress.
concurrent_mark()->abort();
// Make sure we'll choose a new allocation region afterwards.
release_mutator_alloc_region();
abandon_gc_alloc_regions();
g1_rem_set()->cleanupHRRS();
{- -------------------------------------------
(1) G1CollectedHeap::tear_down_region_lists() を呼んで,
MasterFreeRegionList の中身を空にしておく
(中身は, 後で G1CollectedHeap::rebuild_region_lists() によって再構築する).
---------------------------------------- -}
tear_down_region_lists();
// We may have added regions to the current incremental collection
// set between the last GC or pause and now. We need to clear the
// incremental collection set and then start rebuilding it afresh
// after this full GC.
abandon_collection_set(g1_policy()->inc_cset_head());
g1_policy()->clear_incremental_cset();
g1_policy()->stop_incremental_cset_building();
if (g1_policy()->in_young_gc_mode()) {
empty_young_list();
g1_policy()->set_full_young_gcs(true);
}
// See the comment in G1CollectedHeap::ref_processing_init() about
// how reference processing currently works in G1.
// Temporarily make reference _discovery_ single threaded (non-MT).
ReferenceProcessorMTDiscoveryMutator rp_disc_ser(ref_processor(), false);
// Temporarily make refs discovery atomic
ReferenceProcessorAtomicMutator rp_disc_atomic(ref_processor(), true);
// Temporarily clear _is_alive_non_header
ReferenceProcessorIsAliveMutator rp_is_alive_null(ref_processor(), NULL);
ref_processor()->enable_discovery();
ref_processor()->setup_policy(do_clear_all_soft_refs);
{- -------------------------------------------
(1) G1MarkSweep::invoke_at_safepoint() を呼んで, Full GC を実行する.
---------------------------------------- -}
// Do collection work
{
HandleMark hm; // Discard invalid handles created during gc
G1MarkSweep::invoke_at_safepoint(ref_processor(), do_clear_all_soft_refs);
}
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
assert(free_regions() == 0, "we should not have added any free regions");
{- -------------------------------------------
(1) G1CollectedHeap::rebuild_region_lists() を呼んで,
MasterFreeRegionList の中身を正しく設定する.
---------------------------------------- -}
rebuild_region_lists();
{- -------------------------------------------
(1)
---------------------------------------- -}
_summary_bytes_used = recalculate_used();
{- -------------------------------------------
(1) 参照オブジェクト(java.lang.ref オブジェクト)に対する後始末を行う.
(ReferenceProcessor::enqueue_discovered_references() で
リストに残った参照オブジェクト(= 差し先が死んだため特殊な処理が必要な参照オブジェクト)を pending list に追加する)
---------------------------------------- -}
ref_processor()->enqueue_discovered_references();
{- -------------------------------------------
(1) #ifdef COMPILER2 の場合には, GC が終わったので
見つかった derived pointer の値を修正しておく.
(See: DerivedPointerTable)
---------------------------------------- -}
COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
{- -------------------------------------------
(1) (プロファイル情報の記録)(JMM 用) (See: MemoryUsage)
及び (JMM のフック点) でもある (See: LowMemoryDetector)
---------------------------------------- -}
MemoryService::track_memory_usage();
{- -------------------------------------------
(1) (verify)
---------------------------------------- -}
if (VerifyAfterGC && total_collections() >= VerifyGCStartAt) {
HandleMark hm; // Discard invalid handles created during verification
gclog_or_tty->print(" VerifyAfterGC:");
prepare_for_verify();
Universe::verify(false);
}
NOT_PRODUCT(ref_processor()->verify_no_references_recorded());
{- -------------------------------------------
(1)
---------------------------------------- -}
reset_gc_time_stamp();
// Since everything potentially moved, we will clear all remembered
// sets, and clear all cards. Later we will rebuild remebered
// sets. We will also reset the GC time stamps of the regions.
PostMCRemSetClearClosure rs_clear(mr_bs());
heap_region_iterate(&rs_clear);
{- -------------------------------------------
(1)
---------------------------------------- -}
// Resize the heap if necessary.
resize_if_necessary_after_full_collection(explicit_gc ? 0 : word_size);
if (_cg1r->use_cache()) {
_cg1r->clear_and_record_card_counts();
_cg1r->clear_hot_cache();
}
{- -------------------------------------------
(1)
---------------------------------------- -}
// Rebuild remembered sets of all regions.
if (G1CollectedHeap::use_parallel_gc_threads()) {
ParRebuildRSTask rebuild_rs_task(this);
assert(check_heap_region_claim_values(
HeapRegion::InitialClaimValue), "sanity check");
set_par_threads(workers()->total_workers());
workers()->run_task(&rebuild_rs_task);
set_par_threads(0);
assert(check_heap_region_claim_values(
HeapRegion::RebuildRSClaimValue), "sanity check");
reset_heap_region_claim_values();
} else {
RebuildRSOutOfRegionClosure rebuild_rs(this);
heap_region_iterate(&rebuild_rs);
}
{- -------------------------------------------
(1) (トレース出力)
---------------------------------------- -}
if (PrintGC) {
print_size_transition(gclog_or_tty, g1h_prev_used, used(), capacity());
}
{- -------------------------------------------
(1)
---------------------------------------- -}
if (true) { // FIXME
// Ask the permanent generation to adjust size for full collections
perm()->compute_new_size();
}
{- -------------------------------------------
(1)
---------------------------------------- -}
// Start a new incremental collection set for the next pause
assert(g1_policy()->collection_set() == NULL, "must be");
g1_policy()->start_incremental_cset_building();
// Clear the _cset_fast_test bitmap in anticipation of adding
// regions to the incremental collection set for the next
// evacuation pause.
clear_cset_fast_test();
init_mutator_alloc_region();
double end = os::elapsedTime();
g1_policy()->record_full_collection_end();
#ifdef TRACESPINNING
ParallelTaskTerminator::print_termination_counts();
#endif
gc_epilogue(true);
// Discard all rset updates
JavaThread::dirty_card_queue_set().abandon_logs();
assert(!G1DeferredRSUpdate
|| (G1DeferredRSUpdate && (dirty_card_queue_set().completed_buffers_num() == 0)), "Should not be any");
}
{- -------------------------------------------
(1)
---------------------------------------- -}
if (g1_policy()->in_young_gc_mode()) {
_young_list->reset_sampled_info();
// At this point there should be no regions in the
// entire heap tagged as young.
assert( check_young_list_empty(true /* check_heap */),
"young list should be empty at this point");
}
{- -------------------------------------------
(1) (Full GC の完了を待っているスレッドがいるかもしれないので)
G1CollectedHeap::increment_full_collections_completed() を呼び出して
待っているスレッドがいれば起床させておく.
(See: VM_G1IncCollectionPause::doit_epilogue())
---------------------------------------- -}
// Update the number of full collections that have been completed.
increment_full_collections_completed(false /* concurrent */);
{- -------------------------------------------
(1) (verify)
---------------------------------------- -}
verify_region_sets_optional();
{- -------------------------------------------
(1) (トレース出力)
---------------------------------------- -}
if (PrintHeapAtGC) {
Universe::print_heap_after_gc();
}
{- -------------------------------------------
(1) (プロファイル情報の記録) (JMM 用)
(See: G1MonitoringSupport::update_counters())
---------------------------------------- -}
g1mm()->update_counters();
{- -------------------------------------------
(1) リターン
---------------------------------------- -}
return true;
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.