From a996cc8f40b62b82c8d14c0419897b4dc1aaaf30 Mon Sep 17 00:00:00 2001 From: tschatzl Date: Thu, 16 May 2013 13:02:33 +0200 Subject: [PATCH] 8014240: G1: Add remembered set size information to output of G1PrintRegionLivenessInfo Summary: Improve the output of G1PrintRegionLivenessInfo by adding a per-region remembered set size information column Reviewed-by: jwilhelm, johnc --- .../gc_implementation/g1/concurrentMark.cpp | 52 ++++++----- .../gc_implementation/g1/concurrentMark.hpp | 3 + .../gc_implementation/g1/heapRegionRemSet.cpp | 9 +- .../g1/TestPrintRegionRememberedSetInfo.java | 92 +++++++++++++++++++ 4 files changed, 131 insertions(+), 25 deletions(-) create mode 100644 test/gc/g1/TestPrintRegionRememberedSetInfo.java diff --git a/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/src/share/vm/gc_implementation/g1/concurrentMark.cpp index 39e5a2792..137f76c09 100644 --- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp +++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp @@ -4515,7 +4515,8 @@ G1PrintRegionLivenessInfoClosure(outputStream* out, const char* phase_name) _total_used_bytes(0), _total_capacity_bytes(0), _total_prev_live_bytes(0), _total_next_live_bytes(0), _hum_used_bytes(0), _hum_capacity_bytes(0), - _hum_prev_live_bytes(0), _hum_next_live_bytes(0) { + _hum_prev_live_bytes(0), _hum_next_live_bytes(0), + _total_remset_bytes(0) { G1CollectedHeap* g1h = G1CollectedHeap::heap(); MemRegion g1_committed = g1h->g1_committed(); MemRegion g1_reserved = g1h->g1_reserved(); @@ -4533,23 +4534,25 @@ G1PrintRegionLivenessInfoClosure(outputStream* out, const char* phase_name) HeapRegion::GrainBytes); _out->print_cr(G1PPRL_LINE_PREFIX); _out->print_cr(G1PPRL_LINE_PREFIX - G1PPRL_TYPE_H_FORMAT - G1PPRL_ADDR_BASE_H_FORMAT - G1PPRL_BYTE_H_FORMAT - G1PPRL_BYTE_H_FORMAT - G1PPRL_BYTE_H_FORMAT - G1PPRL_DOUBLE_H_FORMAT, - "type", "address-range", - "used", "prev-live", "next-live", "gc-eff"); + G1PPRL_TYPE_H_FORMAT + G1PPRL_ADDR_BASE_H_FORMAT + G1PPRL_BYTE_H_FORMAT + G1PPRL_BYTE_H_FORMAT + G1PPRL_BYTE_H_FORMAT + G1PPRL_DOUBLE_H_FORMAT + G1PPRL_BYTE_H_FORMAT, + "type", "address-range", + "used", "prev-live", "next-live", "gc-eff", "remset"); _out->print_cr(G1PPRL_LINE_PREFIX - G1PPRL_TYPE_H_FORMAT - G1PPRL_ADDR_BASE_H_FORMAT - G1PPRL_BYTE_H_FORMAT - G1PPRL_BYTE_H_FORMAT - G1PPRL_BYTE_H_FORMAT - G1PPRL_DOUBLE_H_FORMAT, - "", "", - "(bytes)", "(bytes)", "(bytes)", "(bytes/ms)"); + G1PPRL_TYPE_H_FORMAT + G1PPRL_ADDR_BASE_H_FORMAT + G1PPRL_BYTE_H_FORMAT + G1PPRL_BYTE_H_FORMAT + G1PPRL_BYTE_H_FORMAT + G1PPRL_DOUBLE_H_FORMAT + G1PPRL_BYTE_H_FORMAT, + "", "", + "(bytes)", "(bytes)", "(bytes)", "(bytes/ms)", "(bytes)"); } // It takes as a parameter a reference to one of the _hum_* fields, it @@ -4591,6 +4594,7 @@ bool G1PrintRegionLivenessInfoClosure::doHeapRegion(HeapRegion* r) { size_t prev_live_bytes = r->live_bytes(); size_t next_live_bytes = r->next_live_bytes(); double gc_eff = r->gc_efficiency(); + size_t remset_bytes = r->rem_set()->mem_size(); if (r->used() == 0) { type = "FREE"; } else if (r->is_survivor()) { @@ -4624,6 +4628,7 @@ bool G1PrintRegionLivenessInfoClosure::doHeapRegion(HeapRegion* r) { _total_capacity_bytes += capacity_bytes; _total_prev_live_bytes += prev_live_bytes; _total_next_live_bytes += next_live_bytes; + _total_remset_bytes += remset_bytes; // Print a line for this particular region. _out->print_cr(G1PPRL_LINE_PREFIX @@ -4632,14 +4637,17 @@ bool G1PrintRegionLivenessInfoClosure::doHeapRegion(HeapRegion* r) { G1PPRL_BYTE_FORMAT G1PPRL_BYTE_FORMAT G1PPRL_BYTE_FORMAT - G1PPRL_DOUBLE_FORMAT, + G1PPRL_DOUBLE_FORMAT + G1PPRL_BYTE_FORMAT, type, bottom, end, - used_bytes, prev_live_bytes, next_live_bytes, gc_eff); + used_bytes, prev_live_bytes, next_live_bytes, gc_eff , remset_bytes); return false; } G1PrintRegionLivenessInfoClosure::~G1PrintRegionLivenessInfoClosure() { + // add static memory usages to remembered set sizes + _total_remset_bytes += HeapRegionRemSet::fl_mem_size() + HeapRegionRemSet::static_mem_size(); // Print the footer of the output. _out->print_cr(G1PPRL_LINE_PREFIX); _out->print_cr(G1PPRL_LINE_PREFIX @@ -4647,13 +4655,15 @@ G1PrintRegionLivenessInfoClosure::~G1PrintRegionLivenessInfoClosure() { G1PPRL_SUM_MB_FORMAT("capacity") G1PPRL_SUM_MB_PERC_FORMAT("used") G1PPRL_SUM_MB_PERC_FORMAT("prev-live") - G1PPRL_SUM_MB_PERC_FORMAT("next-live"), + G1PPRL_SUM_MB_PERC_FORMAT("next-live") + G1PPRL_SUM_MB_FORMAT("remset"), bytes_to_mb(_total_capacity_bytes), bytes_to_mb(_total_used_bytes), perc(_total_used_bytes, _total_capacity_bytes), bytes_to_mb(_total_prev_live_bytes), perc(_total_prev_live_bytes, _total_capacity_bytes), bytes_to_mb(_total_next_live_bytes), - perc(_total_next_live_bytes, _total_capacity_bytes)); + perc(_total_next_live_bytes, _total_capacity_bytes), + bytes_to_mb(_total_remset_bytes)); _out->cr(); } diff --git a/src/share/vm/gc_implementation/g1/concurrentMark.hpp b/src/share/vm/gc_implementation/g1/concurrentMark.hpp index 211a728e2..58ef49e1f 100644 --- a/src/share/vm/gc_implementation/g1/concurrentMark.hpp +++ b/src/share/vm/gc_implementation/g1/concurrentMark.hpp @@ -1257,6 +1257,9 @@ private: size_t _hum_prev_live_bytes; size_t _hum_next_live_bytes; + // Accumulator for the remembered set size + size_t _total_remset_bytes; + static double perc(size_t val, size_t total) { if (total == 0) { return 0.0; diff --git a/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp b/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp index 1e005a26e..e0cf59d5c 100644 --- a/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp +++ b/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp @@ -706,10 +706,11 @@ size_t OtherRegionsTable::mem_size() const { // Cast away const in this case. MutexLockerEx x((Mutex*)&_m, Mutex::_no_safepoint_check_flag); size_t sum = 0; - PerRegionTable * cur = _first_all_fine_prts; - while (cur != NULL) { - sum += cur->mem_size(); - cur = cur->next(); + // all PRTs are of the same size so it is sufficient to query only one of them. + if (_first_all_fine_prts != NULL) { + assert(_last_all_fine_prts != NULL && + _first_all_fine_prts->mem_size() == _last_all_fine_prts->mem_size(), "check that mem_size() is constant"); + sum += _first_all_fine_prts->mem_size() * _n_fine_entries; } sum += (sizeof(PerRegionTable*) * _max_fine_entries); sum += (_coarse_map.size_in_words() * HeapWordSize); diff --git a/test/gc/g1/TestPrintRegionRememberedSetInfo.java b/test/gc/g1/TestPrintRegionRememberedSetInfo.java new file mode 100644 index 000000000..417b2cc1a --- /dev/null +++ b/test/gc/g1/TestPrintRegionRememberedSetInfo.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test TestPrintRegionRememberedSetInfo + * @key gc + * @bug 8014240 + * @summary Test output of G1PrintRegionRememberedSetInfo + * @library /testlibrary + * @build TestPrintRegionRememberedSetInfo + * @author thomas.schatzl@oracle.com + */ + +import com.oracle.java.testlibrary.*; +import java.lang.Thread; +import java.util.ArrayList; +import java.util.Arrays; + +class RunAndWaitForMarking { + public static void main(String[] args) { + System.gc(); + try { + Thread.sleep(200); + } catch (InterruptedException e) { + } + } +} + +public class TestPrintRegionRememberedSetInfo { + + public static String runTest(String arg) throws Exception { + ArrayList finalargs = new ArrayList(); + String[] defaultArgs = new String[] { + "-XX:+UseG1GC", + "-Xmx10m", + "-XX:+ExplicitGCInvokesConcurrent", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+G1PrintRegionLivenessInfo", + "-XX:G1HeapRegionSize=1M", + "-XX:InitiatingHeapOccupancyPercent=0", + }; + + finalargs.addAll(Arrays.asList(defaultArgs)); + finalargs.add(arg); + + finalargs.add(RunAndWaitForMarking.class.getName()); + + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + finalargs.toArray(new String[0])); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldHaveExitValue(0); + + String result = output.getStdout(); + return result; + } + + public static void main(String[] args) throws Exception { + String result; + + result = runTest("-XX:+G1PrintRegionLivenessInfo"); + // check that we got region statistics output + if (result.indexOf("PHASE") == -1) { + throw new RuntimeException("Unexpected output from -XX:+PrintRegionLivenessInfo found."); + } + + result = runTest("-XX:-G1PrintRegionLivenessInfo"); + if (result.indexOf("remset") != -1) { + throw new RuntimeException("Should find remembered set information in output."); + } + } +} + -- GitLab