提交 1f221da7 编写于 作者: J johnc

7068215: G1: Print reference processing time during remark

Summary: Displays the elapsed time taken to perform reference processing during remark as part of the PrintGCDetails output.
Reviewed-by: ysr
上级 9ab02dd4
...@@ -2163,71 +2163,84 @@ void G1RefProcTaskExecutor::execute(EnqueueTask& enq_task) { ...@@ -2163,71 +2163,84 @@ void G1RefProcTaskExecutor::execute(EnqueueTask& enq_task) {
void ConcurrentMark::weakRefsWork(bool clear_all_soft_refs) { void ConcurrentMark::weakRefsWork(bool clear_all_soft_refs) {
ResourceMark rm; ResourceMark rm;
HandleMark hm; HandleMark hm;
G1CollectedHeap* g1h = G1CollectedHeap::heap();
ReferenceProcessor* rp = g1h->ref_processor();
// See the comment in G1CollectedHeap::ref_processing_init() G1CollectedHeap* g1h = G1CollectedHeap::heap();
// about how reference processing currently works in G1.
// Is alive closure.
G1CMIsAliveClosure g1_is_alive(g1h);
// Inner scope to exclude the cleaning of the string and symbol
// tables from the displayed time.
{
bool verbose = PrintGC && PrintGCDetails;
if (verbose) {
gclog_or_tty->put(' ');
}
TraceTime t("GC ref-proc", verbose, false, gclog_or_tty);
// Process weak references. ReferenceProcessor* rp = g1h->ref_processor();
rp->setup_policy(clear_all_soft_refs);
assert(_markStack.isEmpty(), "mark stack should be empty");
G1CMIsAliveClosure g1_is_alive(g1h); // See the comment in G1CollectedHeap::ref_processing_init()
G1CMKeepAliveClosure g1_keep_alive(g1h, this, nextMarkBitMap()); // about how reference processing currently works in G1.
G1CMDrainMarkingStackClosure
g1_drain_mark_stack(nextMarkBitMap(), &_markStack, &g1_keep_alive);
// We use the work gang from the G1CollectedHeap and we utilize all
// the worker threads.
int active_workers = g1h->workers() ? g1h->workers()->total_workers() : 1;
active_workers = MAX2(MIN2(active_workers, (int)_max_task_num), 1);
G1RefProcTaskExecutor par_task_executor(g1h, this, nextMarkBitMap(), // Process weak references.
g1h->workers(), active_workers); rp->setup_policy(clear_all_soft_refs);
assert(_markStack.isEmpty(), "mark stack should be empty");
G1CMKeepAliveClosure g1_keep_alive(g1h, this, nextMarkBitMap());
G1CMDrainMarkingStackClosure
g1_drain_mark_stack(nextMarkBitMap(), &_markStack, &g1_keep_alive);
if (rp->processing_is_mt()) { // We use the work gang from the G1CollectedHeap and we utilize all
// Set the degree of MT here. If the discovery is done MT, there // the worker threads.
// may have been a different number of threads doing the discovery int active_workers = g1h->workers() ? g1h->workers()->total_workers() : 1;
// and a different number of discovered lists may have Ref objects. active_workers = MAX2(MIN2(active_workers, (int)_max_task_num), 1);
// That is OK as long as the Reference lists are balanced (see
// balance_all_queues() and balance_queues()).
rp->set_active_mt_degree(active_workers);
rp->process_discovered_references(&g1_is_alive, G1RefProcTaskExecutor par_task_executor(g1h, this, nextMarkBitMap(),
g1h->workers(), active_workers);
if (rp->processing_is_mt()) {
// Set the degree of MT here. If the discovery is done MT, there
// may have been a different number of threads doing the discovery
// and a different number of discovered lists may have Ref objects.
// That is OK as long as the Reference lists are balanced (see
// balance_all_queues() and balance_queues()).
rp->set_active_mt_degree(active_workers);
rp->process_discovered_references(&g1_is_alive,
&g1_keep_alive, &g1_keep_alive,
&g1_drain_mark_stack, &g1_drain_mark_stack,
&par_task_executor); &par_task_executor);
// The work routines of the parallel keep_alive and drain_marking_stack // The work routines of the parallel keep_alive and drain_marking_stack
// will set the has_overflown flag if we overflow the global marking // will set the has_overflown flag if we overflow the global marking
// stack. // stack.
} else { } else {
rp->process_discovered_references(&g1_is_alive, rp->process_discovered_references(&g1_is_alive,
&g1_keep_alive, &g1_keep_alive,
&g1_drain_mark_stack, &g1_drain_mark_stack,
NULL); NULL);
}
} assert(_markStack.overflow() || _markStack.isEmpty(),
"mark stack should be empty (unless it overflowed)");
if (_markStack.overflow()) {
// Should have been done already when we tried to push an
// entry on to the global mark stack. But let's do it again.
set_has_overflown();
}
assert(_markStack.overflow() || _markStack.isEmpty(), if (rp->processing_is_mt()) {
"mark stack should be empty (unless it overflowed)"); assert(rp->num_q() == active_workers, "why not");
if (_markStack.overflow()) { rp->enqueue_discovered_references(&par_task_executor);
// Should have been done already when we tried to push an } else {
// entry on to the global mark stack. But let's do it again. rp->enqueue_discovered_references();
set_has_overflown(); }
}
if (rp->processing_is_mt()) { rp->verify_no_references_recorded();
assert(rp->num_q() == active_workers, "why not"); assert(!rp->discovery_enabled(), "should have been disabled");
rp->enqueue_discovered_references(&par_task_executor);
} else {
rp->enqueue_discovered_references();
} }
rp->verify_no_references_recorded();
assert(!rp->discovery_enabled(), "should have been disabled");
// Now clean up stale oops in StringTable // Now clean up stale oops in StringTable
StringTable::unlink(&g1_is_alive); StringTable::unlink(&g1_is_alive);
// Clean up unreferenced symbols in symbol table. // Clean up unreferenced symbols in symbol table.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册