hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
void CMTask::regular_clock_call() {
{- -------------------------------------------
(1) 何らかの理由でこの CMTask が中断されていたら, ここでリターン
---------------------------------------- -}
if (has_aborted())
return;
{- -------------------------------------------
(1)
---------------------------------------- -}
// First, we need to recalculate the words scanned and refs reached
// limits for the next clock call.
recalculate_limits();
{- -------------------------------------------
(1) 以下のチェックを行う.
(1) ...
(2) ...
(3) ...
(4) ...
(5) ...
(6) ...
---------------------------------------- -}
// During the regular clock call we do the following
// (1) If an overflow has been flagged, then we abort.
if (_cm->has_overflown()) {
set_has_aborted();
return;
}
// If we are not concurrent (i.e. we're doing remark) we don't need
// to check anything else. The other steps are only needed during
// the concurrent marking phase.
if (!concurrent())
return;
// (2) If marking has been aborted for Full GC, then we also abort.
if (_cm->has_aborted()) {
set_has_aborted();
statsOnly( ++_aborted_cm_aborted );
return;
}
double curr_time_ms = os::elapsedVTime() * 1000.0;
// (3) If marking stats are enabled, then we update the step history.
#if _MARKING_STATS_
if (_words_scanned >= _words_scanned_limit)
++_clock_due_to_scanning;
if (_refs_reached >= _refs_reached_limit)
++_clock_due_to_marking;
double last_interval_ms = curr_time_ms - _interval_start_time_ms;
_interval_start_time_ms = curr_time_ms;
_all_clock_intervals_ms.add(last_interval_ms);
if (_cm->verbose_medium()) {
gclog_or_tty->print_cr("[%d] regular clock, interval = %1.2lfms, "
"scanned = %d%s, refs reached = %d%s",
_task_id, last_interval_ms,
_words_scanned,
(_words_scanned >= _words_scanned_limit) ? " (*)" : "",
_refs_reached,
(_refs_reached >= _refs_reached_limit) ? " (*)" : "");
}
#endif // _MARKING_STATS_
// (4) We check whether we should yield. If we have to, then we abort.
if (_cm->should_yield()) {
// We should yield. To do this we abort the task. The caller is
// responsible for yielding.
set_has_aborted();
statsOnly( ++_aborted_yield );
return;
}
// (5) We check whether we've reached our time quota. If we have,
// then we abort.
double elapsed_time_ms = curr_time_ms - _start_time_ms;
if (elapsed_time_ms > _time_target_ms) {
set_has_aborted();
_has_timed_out = true;
statsOnly( ++_aborted_timed_out );
return;
}
// (6) Finally, we check whether there are enough completed STAB
// buffers available for processing. If there are, we abort.
SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
if (!_draining_satb_buffers && satb_mq_set.process_completed_buffers()) {
if (_cm->verbose_low())
gclog_or_tty->print_cr("[%d] aborting to deal with pending SATB buffers",
_task_id);
// we do need to process SATB buffers, we'll abort and restart
// the marking task to do so
set_has_aborted();
statsOnly( ++_aborted_satb );
return;
}
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.