mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
7068215: G1: Print reference processing time during remark
Displays the elapsed time taken to perform reference processing during remark as part of the PrintGCDetails output. Reviewed-by: ysr
This commit is contained in:
parent
c5b2025c02
commit
2f83b52706
1 changed files with 64 additions and 51 deletions
|
@ -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.
|
|
||||||
|
|
||||||
// Process weak references.
|
// Is alive closure.
|
||||||
rp->setup_policy(clear_all_soft_refs);
|
G1CMIsAliveClosure g1_is_alive(g1h);
|
||||||
assert(_markStack.isEmpty(), "mark stack should be empty");
|
|
||||||
|
|
||||||
G1CMIsAliveClosure g1_is_alive(g1h);
|
// Inner scope to exclude the cleaning of the string and symbol
|
||||||
G1CMKeepAliveClosure g1_keep_alive(g1h, this, nextMarkBitMap());
|
// tables from the displayed time.
|
||||||
G1CMDrainMarkingStackClosure
|
{
|
||||||
g1_drain_mark_stack(nextMarkBitMap(), &_markStack, &g1_keep_alive);
|
bool verbose = PrintGC && PrintGCDetails;
|
||||||
// We use the work gang from the G1CollectedHeap and we utilize all
|
if (verbose) {
|
||||||
// the worker threads.
|
gclog_or_tty->put(' ');
|
||||||
int active_workers = g1h->workers() ? g1h->workers()->total_workers() : 1;
|
}
|
||||||
active_workers = MAX2(MIN2(active_workers, (int)_max_task_num), 1);
|
TraceTime t("GC ref-proc", verbose, false, gclog_or_tty);
|
||||||
|
|
||||||
G1RefProcTaskExecutor par_task_executor(g1h, this, nextMarkBitMap(),
|
ReferenceProcessor* rp = g1h->ref_processor();
|
||||||
g1h->workers(), active_workers);
|
|
||||||
|
|
||||||
|
// See the comment in G1CollectedHeap::ref_processing_init()
|
||||||
|
// about how reference processing currently works in G1.
|
||||||
|
|
||||||
if (rp->processing_is_mt()) {
|
// Process weak references.
|
||||||
// Set the degree of MT here. If the discovery is done MT, there
|
rp->setup_policy(clear_all_soft_refs);
|
||||||
// may have been a different number of threads doing the discovery
|
assert(_markStack.isEmpty(), "mark stack should be empty");
|
||||||
// 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,
|
G1CMKeepAliveClosure g1_keep_alive(g1h, this, nextMarkBitMap());
|
||||||
|
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(),
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rp->processing_is_mt()) {
|
||||||
|
assert(rp->num_q() == active_workers, "why not");
|
||||||
|
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");
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rp->processing_is_mt()) {
|
|
||||||
assert(rp->num_q() == active_workers, "why not");
|
|
||||||
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.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue