8014078: G1: improve remembered set summary information by providing per region type information

Thu, 26 Sep 2013 12:49:45 +0200

author
tschatzl
date
Thu, 26 Sep 2013 12:49:45 +0200
changeset 5807
c319b188c7b2
parent 5774
03f493ce3a71
child 5808
bc918fd1e584
child 5809
4fa18058548e

8014078: G1: improve remembered set summary information by providing per region type information
Summary: Add memory consumption breakdown on a per region type in the G1 remembered set summary statistics. This simplifies remembered set memory consumption analysis.
Reviewed-by: brutisso

src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp file | annotate | diff | comparison | revisions
src/share/vm/gc_implementation/g1/g1RemSet.cpp file | annotate | diff | comparison | revisions
src/share/vm/gc_implementation/g1/g1RemSet.hpp file | annotate | diff | comparison | revisions
src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp file | annotate | diff | comparison | revisions
test/gc/g1/TestSummarizeRSetStats.java file | annotate | diff | comparison | revisions
test/gc/g1/TestSummarizeRSetStatsPerRegion.java file | annotate | diff | comparison | revisions
test/gc/g1/TestSummarizeRSetStatsTools.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Wed Sep 25 17:23:41 2013 +0200
     1.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Thu Sep 26 12:49:45 2013 +0200
     1.3 @@ -3681,6 +3681,11 @@
     1.4    assert(InlineCacheBuffer::is_empty(), "should have cleaned up ICBuffer");
     1.5    // Fill TLAB's and such
     1.6    ensure_parsability(true);
     1.7 +
     1.8 +  if (G1SummarizeRSetStats && (G1SummarizeRSetStatsPeriod > 0) &&
     1.9 +      (total_collections() % G1SummarizeRSetStatsPeriod == 0)) {
    1.10 +    g1_rem_set()->print_periodic_summary_info("Before GC RS summary");
    1.11 +  }
    1.12  }
    1.13  
    1.14  void G1CollectedHeap::gc_epilogue(bool full /* Ignored */) {
    1.15 @@ -3689,7 +3694,7 @@
    1.16        (G1SummarizeRSetStatsPeriod > 0) &&
    1.17        // we are at the end of the GC. Total collections has already been increased.
    1.18        ((total_collections() - 1) % G1SummarizeRSetStatsPeriod == 0)) {
    1.19 -    g1_rem_set()->print_periodic_summary_info();
    1.20 +    g1_rem_set()->print_periodic_summary_info("After GC RS summary");
    1.21    }
    1.22  
    1.23    // FIXME: what is this about?
     2.1 --- a/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Wed Sep 25 17:23:41 2013 +0200
     2.2 +++ b/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Thu Sep 26 12:49:45 2013 +0200
     2.3 @@ -731,12 +731,12 @@
     2.4    return has_refs_into_cset;
     2.5  }
     2.6  
     2.7 -void G1RemSet::print_periodic_summary_info() {
     2.8 +void G1RemSet::print_periodic_summary_info(const char* header) {
     2.9    G1RemSetSummary current;
    2.10    current.initialize(this, n_workers());
    2.11  
    2.12    _prev_period_summary.subtract_from(&current);
    2.13 -  print_summary_info(&_prev_period_summary);
    2.14 +  print_summary_info(&_prev_period_summary, header);
    2.15  
    2.16    _prev_period_summary.set(&current);
    2.17  }
     3.1 --- a/src/share/vm/gc_implementation/g1/g1RemSet.hpp	Wed Sep 25 17:23:41 2013 +0200
     3.2 +++ b/src/share/vm/gc_implementation/g1/g1RemSet.hpp	Thu Sep 26 12:49:45 2013 +0200
     3.3 @@ -145,7 +145,7 @@
     3.4    virtual void print_summary_info();
     3.5  
     3.6    // Print accumulated summary info from the last time called.
     3.7 -  virtual void print_periodic_summary_info();
     3.8 +  virtual void print_periodic_summary_info(const char* header);
     3.9  
    3.10    // Prepare remembered set for verification.
    3.11    virtual void prepare_for_verify();
     4.1 --- a/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp	Wed Sep 25 17:23:41 2013 +0200
     4.2 +++ b/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp	Thu Sep 26 12:49:45 2013 +0200
     4.3 @@ -125,25 +125,115 @@
     4.4    _sampling_thread_vtime = other->sampling_thread_vtime() - _sampling_thread_vtime;
     4.5  }
     4.6  
     4.7 +static double percent_of(size_t numerator, size_t denominator) {
     4.8 +  if (denominator != 0) {
     4.9 +    return (double)numerator / denominator * 100.0f;
    4.10 +  } else {
    4.11 +    return 0.0f;
    4.12 +  }
    4.13 +}
    4.14 +
    4.15 +static size_t round_to_K(size_t value) {
    4.16 +  return value / K;
    4.17 +}
    4.18 +
    4.19 +class RegionTypeCounter VALUE_OBJ_CLASS_SPEC {
    4.20 +private:
    4.21 +  const char* _name;
    4.22 +
    4.23 +  size_t _rs_mem_size;
    4.24 +  size_t _cards_occupied;
    4.25 +  size_t _amount;
    4.26 +
    4.27 +  size_t _code_root_mem_size;
    4.28 +  size_t _code_root_elems;
    4.29 +
    4.30 +  double rs_mem_size_percent_of(size_t total) {
    4.31 +    return percent_of(_rs_mem_size, total);
    4.32 +  }
    4.33 +
    4.34 +  double cards_occupied_percent_of(size_t total) {
    4.35 +    return percent_of(_cards_occupied, total);
    4.36 +  }
    4.37 +
    4.38 +  double code_root_mem_size_percent_of(size_t total) {
    4.39 +    return percent_of(_code_root_mem_size, total);
    4.40 +  }
    4.41 +
    4.42 +  double code_root_elems_percent_of(size_t total) {
    4.43 +    return percent_of(_code_root_elems, total);
    4.44 +  }
    4.45 +
    4.46 +  size_t amount() const { return _amount; }
    4.47 +
    4.48 +public:
    4.49 +
    4.50 +  RegionTypeCounter(const char* name) : _name(name), _rs_mem_size(0), _cards_occupied(0),
    4.51 +    _amount(0), _code_root_mem_size(0), _code_root_elems(0) { }
    4.52 +
    4.53 +  void add(size_t rs_mem_size, size_t cards_occupied, size_t code_root_mem_size,
    4.54 +    size_t code_root_elems) {
    4.55 +    _rs_mem_size += rs_mem_size;
    4.56 +    _cards_occupied += cards_occupied;
    4.57 +    _code_root_mem_size += code_root_mem_size;
    4.58 +    _code_root_elems += code_root_elems;
    4.59 +    _amount++;
    4.60 +  }
    4.61 +
    4.62 +  size_t rs_mem_size() const { return _rs_mem_size; }
    4.63 +  size_t cards_occupied() const { return _cards_occupied; }
    4.64 +
    4.65 +  size_t code_root_mem_size() const { return _code_root_mem_size; }
    4.66 +  size_t code_root_elems() const { return _code_root_elems; }
    4.67 +
    4.68 +  void print_rs_mem_info_on(outputStream * out, size_t total) {
    4.69 +    out->print_cr("    %8dK (%5.1f%%) by %zd %s regions", round_to_K(rs_mem_size()), rs_mem_size_percent_of(total), amount(), _name);
    4.70 +  }
    4.71 +
    4.72 +  void print_cards_occupied_info_on(outputStream * out, size_t total) {
    4.73 +    out->print_cr("     %8d (%5.1f%%) entries by %zd %s regions", cards_occupied(), cards_occupied_percent_of(total), amount(), _name);
    4.74 +  }
    4.75 +
    4.76 +  void print_code_root_mem_info_on(outputStream * out, size_t total) {
    4.77 +    out->print_cr("    %8dK (%5.1f%%) by %zd %s regions", round_to_K(code_root_mem_size()), code_root_mem_size_percent_of(total), amount(), _name);
    4.78 +  }
    4.79 +
    4.80 +  void print_code_root_elems_info_on(outputStream * out, size_t total) {
    4.81 +    out->print_cr("     %8d (%5.1f%%) elements by %zd %s regions", code_root_elems(), code_root_elems_percent_of(total), amount(), _name);
    4.82 +  }
    4.83 +};
    4.84 +
    4.85 +
    4.86  class HRRSStatsIter: public HeapRegionClosure {
    4.87 -  size_t _occupied;
    4.88 +private:
    4.89 +  RegionTypeCounter _young;
    4.90 +  RegionTypeCounter _humonguous;
    4.91 +  RegionTypeCounter _free;
    4.92 +  RegionTypeCounter _old;
    4.93 +  RegionTypeCounter _all;
    4.94  
    4.95 -  size_t _total_rs_mem_sz;
    4.96    size_t _max_rs_mem_sz;
    4.97    HeapRegion* _max_rs_mem_sz_region;
    4.98  
    4.99 -  size_t _total_code_root_mem_sz;
   4.100 +  size_t total_rs_mem_sz() const            { return _all.rs_mem_size(); }
   4.101 +  size_t total_cards_occupied() const       { return _all.cards_occupied(); }
   4.102 +
   4.103 +  size_t max_rs_mem_sz() const              { return _max_rs_mem_sz; }
   4.104 +  HeapRegion* max_rs_mem_sz_region() const  { return _max_rs_mem_sz_region; }
   4.105 +
   4.106    size_t _max_code_root_mem_sz;
   4.107    HeapRegion* _max_code_root_mem_sz_region;
   4.108 +
   4.109 +  size_t total_code_root_mem_sz() const     { return _all.code_root_mem_size(); }
   4.110 +  size_t total_code_root_elems() const      { return _all.code_root_elems(); }
   4.111 +
   4.112 +  size_t max_code_root_mem_sz() const       { return _max_code_root_mem_sz; }
   4.113 +  HeapRegion* max_code_root_mem_sz_region() const { return _max_code_root_mem_sz_region; }
   4.114 +
   4.115  public:
   4.116 -  HRRSStatsIter() :
   4.117 -    _occupied(0),
   4.118 -    _total_rs_mem_sz(0),
   4.119 -    _max_rs_mem_sz(0),
   4.120 -    _max_rs_mem_sz_region(NULL),
   4.121 -    _total_code_root_mem_sz(0),
   4.122 -    _max_code_root_mem_sz(0),
   4.123 -    _max_code_root_mem_sz_region(NULL)
   4.124 +  HRRSStatsIter() : _all("All"), _young("Young"), _humonguous("Humonguous"),
   4.125 +    _free("Free"), _old("Old"), _max_code_root_mem_sz_region(NULL), _max_rs_mem_sz_region(NULL),
   4.126 +    _max_rs_mem_sz(0), _max_code_root_mem_sz(0)
   4.127    {}
   4.128  
   4.129    bool doHeapRegion(HeapRegion* r) {
   4.130 @@ -156,46 +246,95 @@
   4.131        _max_rs_mem_sz = rs_mem_sz;
   4.132        _max_rs_mem_sz_region = r;
   4.133      }
   4.134 -    _total_rs_mem_sz += rs_mem_sz;
   4.135 -
   4.136 +    size_t occupied_cards = hrrs->occupied();
   4.137      size_t code_root_mem_sz = hrrs->strong_code_roots_mem_size();
   4.138 -    if (code_root_mem_sz > _max_code_root_mem_sz) {
   4.139 -      _max_code_root_mem_sz = code_root_mem_sz;
   4.140 +    if (code_root_mem_sz > max_code_root_mem_sz()) {
   4.141        _max_code_root_mem_sz_region = r;
   4.142      }
   4.143 -    _total_code_root_mem_sz += code_root_mem_sz;
   4.144 +    size_t code_root_elems = hrrs->strong_code_roots_list_length();
   4.145  
   4.146 -    size_t occ = hrrs->occupied();
   4.147 -    _occupied += occ;
   4.148 +    RegionTypeCounter* current = NULL;
   4.149 +    if (r->is_young()) {
   4.150 +      current = &_young;
   4.151 +    } else if (r->isHumongous()) {
   4.152 +      current = &_humonguous;
   4.153 +    } else if (r->is_empty()) {
   4.154 +      current = &_free;
   4.155 +    } else {
   4.156 +      current = &_old;
   4.157 +    }
   4.158 +    current->add(rs_mem_sz, occupied_cards, code_root_mem_sz, code_root_elems);
   4.159 +    _all.add(rs_mem_sz, occupied_cards, code_root_mem_sz, code_root_elems);
   4.160 +
   4.161      return false;
   4.162    }
   4.163 -  size_t total_rs_mem_sz() { return _total_rs_mem_sz; }
   4.164 -  size_t max_rs_mem_sz() { return _max_rs_mem_sz; }
   4.165 -  HeapRegion* max_rs_mem_sz_region() { return _max_rs_mem_sz_region; }
   4.166 -  size_t total_code_root_mem_sz() { return _total_code_root_mem_sz; }
   4.167 -  size_t max_code_root_mem_sz() { return _max_code_root_mem_sz; }
   4.168 -  HeapRegion* max_code_root_mem_sz_region() { return _max_code_root_mem_sz_region; }
   4.169 -  size_t occupied() { return _occupied; }
   4.170 +
   4.171 +  void print_summary_on(outputStream* out) {
   4.172 +    RegionTypeCounter* counters[] = { &_young, &_humonguous, &_free, &_old, NULL };
   4.173 +
   4.174 +    out->print_cr("\n Current rem set statistics");
   4.175 +    out->print_cr("  Total per region rem sets sizes = "SIZE_FORMAT"K."
   4.176 +                  " Max = "SIZE_FORMAT"K.",
   4.177 +                  round_to_K(total_rs_mem_sz()), round_to_K(max_rs_mem_sz()));
   4.178 +    for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) {
   4.179 +      (*current)->print_rs_mem_info_on(out, total_rs_mem_sz());
   4.180 +    }
   4.181 +
   4.182 +    out->print_cr("   Static structures = "SIZE_FORMAT"K,"
   4.183 +                  " free_lists = "SIZE_FORMAT"K.",
   4.184 +                  round_to_K(HeapRegionRemSet::static_mem_size()),
   4.185 +                  round_to_K(HeapRegionRemSet::fl_mem_size()));
   4.186 +
   4.187 +    out->print_cr("    "SIZE_FORMAT" occupied cards represented.",
   4.188 +                  total_cards_occupied());
   4.189 +    for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) {
   4.190 +      (*current)->print_cards_occupied_info_on(out, total_cards_occupied());
   4.191 +    }
   4.192 +
   4.193 +    // Largest sized rem set region statistics
   4.194 +    HeapRegionRemSet* rem_set = max_rs_mem_sz_region()->rem_set();
   4.195 +    out->print_cr("    Region with largest rem set = "HR_FORMAT", "
   4.196 +                  "size = "SIZE_FORMAT "K, occupied = "SIZE_FORMAT"K.",
   4.197 +                  HR_FORMAT_PARAMS(max_rs_mem_sz_region()),
   4.198 +                  round_to_K(rem_set->mem_size()),
   4.199 +                  round_to_K(rem_set->occupied()));
   4.200 +
   4.201 +    // Strong code root statistics
   4.202 +    HeapRegionRemSet* max_code_root_rem_set = max_code_root_mem_sz_region()->rem_set();
   4.203 +    out->print_cr("  Total heap region code root sets sizes = "SIZE_FORMAT"K."
   4.204 +                  "  Max = "SIZE_FORMAT"K.",
   4.205 +                  round_to_K(total_code_root_mem_sz()),
   4.206 +                  round_to_K(max_code_root_rem_set->strong_code_roots_mem_size()));
   4.207 +    for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) {
   4.208 +      (*current)->print_code_root_mem_info_on(out, total_code_root_mem_sz());
   4.209 +    }
   4.210 +
   4.211 +    out->print_cr("    "SIZE_FORMAT" code roots represented.",
   4.212 +                  total_code_root_elems());
   4.213 +    for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) {
   4.214 +      (*current)->print_code_root_elems_info_on(out, total_code_root_elems());
   4.215 +    }
   4.216 +
   4.217 +    out->print_cr("    Region with largest amount of code roots = "HR_FORMAT", "
   4.218 +                  "size = "SIZE_FORMAT "K, num_elems = "SIZE_FORMAT".",
   4.219 +                  HR_FORMAT_PARAMS(max_code_root_mem_sz_region()),
   4.220 +                  round_to_K(max_code_root_rem_set->strong_code_roots_mem_size()),
   4.221 +                  round_to_K(max_code_root_rem_set->strong_code_roots_list_length()));
   4.222 +  }
   4.223  };
   4.224  
   4.225 -double calc_percentage(size_t numerator, size_t denominator) {
   4.226 -  if (denominator != 0) {
   4.227 -    return (double)numerator / denominator * 100.0;
   4.228 -  } else {
   4.229 -    return 0.0f;
   4.230 -  }
   4.231 -}
   4.232 -
   4.233  void G1RemSetSummary::print_on(outputStream* out) {
   4.234 -  out->print_cr("\n Concurrent RS processed "SIZE_FORMAT" cards",
   4.235 +  out->print_cr("\n Recent concurrent refinement statistics");
   4.236 +  out->print_cr("  Processed "SIZE_FORMAT" cards",
   4.237                  num_concurrent_refined_cards());
   4.238    out->print_cr("  Of %d completed buffers:", num_processed_buf_total());
   4.239    out->print_cr("     %8d (%5.1f%%) by concurrent RS threads.",
   4.240                  num_processed_buf_total(),
   4.241 -                calc_percentage(num_processed_buf_rs_threads(), num_processed_buf_total()));
   4.242 +                percent_of(num_processed_buf_rs_threads(), num_processed_buf_total()));
   4.243    out->print_cr("     %8d (%5.1f%%) by mutator threads.",
   4.244                  num_processed_buf_mutator(),
   4.245 -                calc_percentage(num_processed_buf_mutator(), num_processed_buf_total()));
   4.246 +                percent_of(num_processed_buf_mutator(), num_processed_buf_total()));
   4.247 +  out->print_cr("  Did %d coarsenings.", num_coarsenings());
   4.248    out->print_cr("  Concurrent RS threads times (s)");
   4.249    out->print("     ");
   4.250    for (uint i = 0; i < _num_vtimes; i++) {
   4.251 @@ -207,33 +346,5 @@
   4.252  
   4.253    HRRSStatsIter blk;
   4.254    G1CollectedHeap::heap()->heap_region_iterate(&blk);
   4.255 -  // RemSet stats
   4.256 -  out->print_cr("  Total heap region rem set sizes = "SIZE_FORMAT"K."
   4.257 -                "  Max = "SIZE_FORMAT"K.",
   4.258 -                blk.total_rs_mem_sz()/K, blk.max_rs_mem_sz()/K);
   4.259 -  out->print_cr("  Static structures = "SIZE_FORMAT"K,"
   4.260 -                " free_lists = "SIZE_FORMAT"K.",
   4.261 -                HeapRegionRemSet::static_mem_size() / K,
   4.262 -                HeapRegionRemSet::fl_mem_size() / K);
   4.263 -  out->print_cr("    "SIZE_FORMAT" occupied cards represented.",
   4.264 -                blk.occupied());
   4.265 -  HeapRegion* max_rs_mem_sz_region = blk.max_rs_mem_sz_region();
   4.266 -  HeapRegionRemSet* max_rs_rem_set = max_rs_mem_sz_region->rem_set();
   4.267 -  out->print_cr("    Max size region = "HR_FORMAT", "
   4.268 -                "size = "SIZE_FORMAT "K, occupied = "SIZE_FORMAT"K.",
   4.269 -                HR_FORMAT_PARAMS(max_rs_mem_sz_region),
   4.270 -                (max_rs_rem_set->mem_size() + K - 1)/K,
   4.271 -                (max_rs_rem_set->occupied() + K - 1)/K);
   4.272 -  out->print_cr("    Did %d coarsenings.", num_coarsenings());
   4.273 -  // Strong code root stats
   4.274 -  out->print_cr("  Total heap region code-root set sizes = "SIZE_FORMAT"K."
   4.275 -                "  Max = "SIZE_FORMAT"K.",
   4.276 -                blk.total_code_root_mem_sz()/K, blk.max_code_root_mem_sz()/K);
   4.277 -  HeapRegion* max_code_root_mem_sz_region = blk.max_code_root_mem_sz_region();
   4.278 -  HeapRegionRemSet* max_code_root_rem_set = max_code_root_mem_sz_region->rem_set();
   4.279 -  out->print_cr("    Max size region = "HR_FORMAT", "
   4.280 -                "size = "SIZE_FORMAT "K, num_elems = "SIZE_FORMAT".",
   4.281 -                HR_FORMAT_PARAMS(max_code_root_mem_sz_region),
   4.282 -                (max_code_root_rem_set->strong_code_roots_mem_size() + K - 1)/K,
   4.283 -                (max_code_root_rem_set->strong_code_roots_list_length()));
   4.284 +  blk.print_summary_on(out);
   4.285  }
     5.1 --- a/test/gc/g1/TestSummarizeRSetStats.java	Wed Sep 25 17:23:41 2013 +0200
     5.2 +++ b/test/gc/g1/TestSummarizeRSetStats.java	Thu Sep 26 12:49:45 2013 +0200
     5.3 @@ -25,140 +25,61 @@
     5.4   * @test TestSummarizeRSetStats.java
     5.5   * @bug 8013895
     5.6   * @library /testlibrary
     5.7 - * @build TestSummarizeRSetStats
     5.8 + * @build TestSummarizeRSetStatsTools TestSummarizeRSetStats
     5.9   * @summary Verify output of -XX:+G1SummarizeRSetStats
    5.10   * @run main TestSummarizeRSetStats
    5.11   *
    5.12   * Test the output of G1SummarizeRSetStats in conjunction with G1SummarizeRSetStatsPeriod.
    5.13   */
    5.14  
    5.15 -import com.oracle.java.testlibrary.*;
    5.16 -import java.lang.Thread;
    5.17 -import java.util.ArrayList;
    5.18 -import java.util.Arrays;
    5.19 -
    5.20 -class RunSystemGCs {
    5.21 -    // 4M size, both are directly allocated into the old gen
    5.22 -    static Object[] largeObject1 = new Object[1024 * 1024];
    5.23 -    static Object[] largeObject2 = new Object[1024 * 1024];
    5.24 -
    5.25 -    static int[] temp;
    5.26 -
    5.27 -    public static void main(String[] args) {
    5.28 -        // create some cross-references between these objects
    5.29 -        for (int i = 0; i < largeObject1.length; i++) {
    5.30 -            largeObject1[i] = largeObject2;
    5.31 -        }
    5.32 -
    5.33 -        for (int i = 0; i < largeObject2.length; i++) {
    5.34 -            largeObject2[i] = largeObject1;
    5.35 -        }
    5.36 -
    5.37 -        int numGCs = Integer.parseInt(args[0]);
    5.38 -
    5.39 -        if (numGCs > 0) {
    5.40 -            // try to force a minor collection: the young gen is 4M, the
    5.41 -            // amount of data allocated below is roughly that (4*1024*1024 +
    5.42 -            // some header data)
    5.43 -            for (int i = 0; i < 1024 ; i++) {
    5.44 -                temp = new int[1024];
    5.45 -            }
    5.46 -        }
    5.47 -
    5.48 -        for (int i = 0; i < numGCs - 1; i++) {
    5.49 -            System.gc();
    5.50 -        }
    5.51 -    }
    5.52 -}
    5.53 -
    5.54  public class TestSummarizeRSetStats {
    5.55  
    5.56 -    public static String runTest(String[] additionalArgs, int numGCs) throws Exception {
    5.57 -        ArrayList<String> finalargs = new ArrayList<String>();
    5.58 -        String[] defaultArgs = new String[] {
    5.59 -            "-XX:+UseG1GC",
    5.60 -            "-Xmn4m",
    5.61 -            "-Xmx20m",
    5.62 -            "-XX:InitiatingHeapOccupancyPercent=100", // we don't want the additional GCs due to initial marking
    5.63 -            "-XX:+PrintGC",
    5.64 -            "-XX:+UnlockDiagnosticVMOptions",
    5.65 -            "-XX:G1HeapRegionSize=1M",
    5.66 -        };
    5.67 -
    5.68 -        finalargs.addAll(Arrays.asList(defaultArgs));
    5.69 -
    5.70 -        if (additionalArgs != null) {
    5.71 -            finalargs.addAll(Arrays.asList(additionalArgs));
    5.72 -        }
    5.73 -
    5.74 -        finalargs.add(RunSystemGCs.class.getName());
    5.75 -        finalargs.add(String.valueOf(numGCs));
    5.76 -
    5.77 -        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
    5.78 -            finalargs.toArray(new String[0]));
    5.79 -        OutputAnalyzer output = new OutputAnalyzer(pb.start());
    5.80 -
    5.81 -        output.shouldHaveExitValue(0);
    5.82 -
    5.83 -        String result = output.getStdout();
    5.84 -        return result;
    5.85 -    }
    5.86 -
    5.87 -    private static void expectStatistics(String result, int expectedCumulative, int expectedPeriodic) throws Exception {
    5.88 -        int actualTotal = result.split("Concurrent RS processed").length - 1;
    5.89 -        int actualCumulative = result.split("Cumulative RS summary").length - 1;
    5.90 -
    5.91 -        if (expectedCumulative != actualCumulative) {
    5.92 -            throw new Exception("Incorrect amount of RSet summaries at the end. Expected " + expectedCumulative + ", got " + actualCumulative);
    5.93 -        }
    5.94 -
    5.95 -        if (expectedPeriodic != (actualTotal - actualCumulative)) {
    5.96 -            throw new Exception("Incorrect amount of per-period RSet summaries at the end. Expected " + expectedPeriodic + ", got " + (actualTotal - actualCumulative));
    5.97 -        }
    5.98 -    }
    5.99 -
   5.100      public static void main(String[] args) throws Exception {
   5.101          String result;
   5.102  
   5.103 -        // no RSet statistics output
   5.104 -        result = runTest(null, 0);
   5.105 -        expectStatistics(result, 0, 0);
   5.106 +        if (!TestSummarizeRSetStatsTools.testingG1GC()) {
   5.107 +            return;
   5.108 +        }
   5.109  
   5.110 -        // no RSet statistics output
   5.111 -        result = runTest(null, 2);
   5.112 -        expectStatistics(result, 0, 0);
   5.113 +        // no remembered set summary output
   5.114 +        result = TestSummarizeRSetStatsTools.runTest(null, 0);
   5.115 +        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 0, 0);
   5.116  
   5.117 -        // no RSet statistics output
   5.118 -        result = runTest(new String[] { "-XX:G1SummarizeRSetStatsPeriod=1" }, 3);
   5.119 -        expectStatistics(result, 0, 0);
   5.120 +        // no remembered set summary output
   5.121 +        result = TestSummarizeRSetStatsTools.runTest(null, 2);
   5.122 +        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 0, 0);
   5.123  
   5.124 -        // single RSet statistics output at the end
   5.125 -        result = runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 0);
   5.126 -        expectStatistics(result, 1, 0);
   5.127 +        // no remembered set summary output
   5.128 +        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:G1SummarizeRSetStatsPeriod=1" }, 3);
   5.129 +        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 0, 0);
   5.130  
   5.131 -        // single RSet statistics output at the end
   5.132 -        result = runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 2);
   5.133 -        expectStatistics(result, 1, 0);
   5.134 +        // single remembered set summary output at the end
   5.135 +        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 0);
   5.136 +        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 0);
   5.137  
   5.138 -        // single RSet statistics output
   5.139 -        result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 0);
   5.140 -        expectStatistics(result, 1, 0);
   5.141 +        // single remembered set summary output at the end
   5.142 +        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 2);
   5.143 +        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 0);
   5.144  
   5.145 -        // two times RSet statistics output
   5.146 -        result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 1);
   5.147 -        expectStatistics(result, 1, 1);
   5.148 +        // single remembered set summary output
   5.149 +        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 0);
   5.150 +        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 0);
   5.151  
   5.152 -        // four times RSet statistics output
   5.153 -        result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 3);
   5.154 -        expectStatistics(result, 1, 3);
   5.155 +        // two times remembered set summary output
   5.156 +        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 1);
   5.157 +        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 2);
   5.158  
   5.159 -        // three times RSet statistics output
   5.160 -        result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=2" }, 3);
   5.161 -        expectStatistics(result, 1, 2);
   5.162 +        // four times remembered set summary output
   5.163 +        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 3);
   5.164 +        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 6);
   5.165  
   5.166 -        // single RSet statistics output
   5.167 -        result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=100" }, 3);
   5.168 -        expectStatistics(result, 1, 1);
   5.169 +        // three times remembered set summary output
   5.170 +        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=2" }, 3);
   5.171 +        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 4);
   5.172 +
   5.173 +        // single remembered set summary output
   5.174 +        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=100" }, 3);
   5.175 +        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 2);
   5.176      }
   5.177  }
   5.178  
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/test/gc/g1/TestSummarizeRSetStatsPerRegion.java	Thu Sep 26 12:49:45 2013 +0200
     6.3 @@ -0,0 +1,55 @@
     6.4 +/*
     6.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
     6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     6.7 + *
     6.8 + * This code is free software; you can redistribute it and/or modify it
     6.9 + * under the terms of the GNU General Public License version 2 only, as
    6.10 + * published by the Free Software Foundation.
    6.11 + *
    6.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    6.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    6.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    6.15 + * version 2 for more details (a copy is included in the LICENSE file that
    6.16 + * accompanied this code).
    6.17 + *
    6.18 + * You should have received a copy of the GNU General Public License version
    6.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    6.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    6.21 + *
    6.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    6.23 + * or visit www.oracle.com if you need additional information or have any
    6.24 + * questions.
    6.25 + */
    6.26 +
    6.27 +/*
    6.28 + * @test TestSummarizeRSetStatsPerRegion.java
    6.29 + * @bug 8014078
    6.30 + * @library /testlibrary
    6.31 + * @build TestSummarizeRSetStatsTools TestSummarizeRSetStatsPerRegion
    6.32 + * @summary Verify output of -XX:+G1SummarizeRSetStats in regards to per-region type output
    6.33 + * @run main TestSummarizeRSetStatsPerRegion
    6.34 + */
    6.35 +
    6.36 +import com.oracle.java.testlibrary.*;
    6.37 +import java.lang.Thread;
    6.38 +import java.util.ArrayList;
    6.39 +import java.util.Arrays;
    6.40 +
    6.41 +public class TestSummarizeRSetStatsPerRegion {
    6.42 +
    6.43 +    public static void main(String[] args) throws Exception {
    6.44 +        String result;
    6.45 +
    6.46 +        if (!TestSummarizeRSetStatsTools.testingG1GC()) {
    6.47 +            return;
    6.48 +        }
    6.49 +
    6.50 +        // single remembered set summary output at the end
    6.51 +        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 0);
    6.52 +        TestSummarizeRSetStatsTools.expectPerRegionRSetSummaries(result, 1, 0);
    6.53 +
    6.54 +        // two times remembered set summary output
    6.55 +        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 1);
    6.56 +        TestSummarizeRSetStatsTools.expectPerRegionRSetSummaries(result, 1, 2);
    6.57 +    }
    6.58 +}
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/test/gc/g1/TestSummarizeRSetStatsTools.java	Thu Sep 26 12:49:45 2013 +0200
     7.3 @@ -0,0 +1,154 @@
     7.4 +/*
     7.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
     7.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     7.7 + *
     7.8 + * This code is free software; you can redistribute it and/or modify it
     7.9 + * under the terms of the GNU General Public License version 2 only, as
    7.10 + * published by the Free Software Foundation.
    7.11 + *
    7.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    7.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    7.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    7.15 + * version 2 for more details (a copy is included in the LICENSE file that
    7.16 + * accompanied this code).
    7.17 + *
    7.18 + * You should have received a copy of the GNU General Public License version
    7.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    7.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    7.21 + *
    7.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    7.23 + * or visit www.oracle.com if you need additional information or have any
    7.24 + * questions.
    7.25 + */
    7.26 +
    7.27 +/*
    7.28 + * Common helpers for TestSummarizeRSetStats* tests
    7.29 + */
    7.30 +
    7.31 +import sun.management.ManagementFactoryHelper;
    7.32 +import com.sun.management.HotSpotDiagnosticMXBean;
    7.33 +import com.sun.management.VMOption;
    7.34 +
    7.35 +import com.oracle.java.testlibrary.*;
    7.36 +import java.util.regex.Matcher;
    7.37 +import java.util.regex.Pattern;
    7.38 +import java.lang.Thread;
    7.39 +import java.util.ArrayList;
    7.40 +import java.util.Arrays;
    7.41 +
    7.42 +class VerifySummaryOutput {
    7.43 +    // 4M size, both are directly allocated into the old gen
    7.44 +    static Object[] largeObject1 = new Object[1024 * 1024];
    7.45 +    static Object[] largeObject2 = new Object[1024 * 1024];
    7.46 +
    7.47 +    static int[] temp;
    7.48 +
    7.49 +    public static void main(String[] args) {
    7.50 +        // create some cross-references between these objects
    7.51 +        for (int i = 0; i < largeObject1.length; i++) {
    7.52 +            largeObject1[i] = largeObject2;
    7.53 +        }
    7.54 +
    7.55 +        for (int i = 0; i < largeObject2.length; i++) {
    7.56 +            largeObject2[i] = largeObject1;
    7.57 +        }
    7.58 +
    7.59 +        int numGCs = Integer.parseInt(args[0]);
    7.60 +
    7.61 +        if (numGCs > 0) {
    7.62 +            // try to force a minor collection: the young gen is 4M, the
    7.63 +            // amount of data allocated below is roughly that (4*1024*1024 +
    7.64 +            // some header data)
    7.65 +            for (int i = 0; i < 1024 ; i++) {
    7.66 +                temp = new int[1024];
    7.67 +            }
    7.68 +        }
    7.69 +
    7.70 +        for (int i = 0; i < numGCs - 1; i++) {
    7.71 +            System.gc();
    7.72 +        }
    7.73 +    }
    7.74 +}
    7.75 +
    7.76 +public class TestSummarizeRSetStatsTools {
    7.77 +
    7.78 +    // the VM is currently run using G1GC, i.e. trying to test G1 functionality.
    7.79 +    public static boolean testingG1GC() {
    7.80 +        HotSpotDiagnosticMXBean diagnostic = ManagementFactoryHelper.getDiagnosticMXBean();
    7.81 +
    7.82 +        VMOption option = diagnostic.getVMOption("UseG1GC");
    7.83 +        if (option.getValue().equals("false")) {
    7.84 +          System.out.println("Skipping this test. It is only a G1 test.");
    7.85 +          return false;
    7.86 +        }
    7.87 +        return true;
    7.88 +    }
    7.89 +
    7.90 +    public static String runTest(String[] additionalArgs, int numGCs) throws Exception {
    7.91 +        ArrayList<String> finalargs = new ArrayList<String>();
    7.92 +        String[] defaultArgs = new String[] {
    7.93 +            "-XX:+UseG1GC",
    7.94 +            "-XX:+UseCompressedOops",
    7.95 +            "-Xmn4m",
    7.96 +            "-Xmx20m",
    7.97 +            "-XX:InitiatingHeapOccupancyPercent=100", // we don't want the additional GCs due to initial marking
    7.98 +            "-XX:+PrintGC",
    7.99 +            "-XX:+UnlockDiagnosticVMOptions",
   7.100 +            "-XX:G1HeapRegionSize=1M",
   7.101 +        };
   7.102 +
   7.103 +        finalargs.addAll(Arrays.asList(defaultArgs));
   7.104 +
   7.105 +        if (additionalArgs != null) {
   7.106 +            finalargs.addAll(Arrays.asList(additionalArgs));
   7.107 +        }
   7.108 +
   7.109 +        finalargs.add(VerifySummaryOutput.class.getName());
   7.110 +        finalargs.add(String.valueOf(numGCs));
   7.111 +
   7.112 +        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
   7.113 +            finalargs.toArray(new String[0]));
   7.114 +        OutputAnalyzer output = new OutputAnalyzer(pb.start());
   7.115 +
   7.116 +        output.shouldHaveExitValue(0);
   7.117 +
   7.118 +        String result = output.getStdout();
   7.119 +        return result;
   7.120 +    }
   7.121 +
   7.122 +    private static void checkCounts(int expected, int actual, String which) throws Exception {
   7.123 +        if (expected != actual) {
   7.124 +            throw new Exception("RSet summaries mention " + which + " regions an incorrect number of times. Expected " + expected + ", got " + actual);
   7.125 +        }
   7.126 +    }
   7.127 +
   7.128 +    public static void expectPerRegionRSetSummaries(String result, int expectedCumulative, int expectedPeriodic) throws Exception {
   7.129 +        expectRSetSummaries(result, expectedCumulative, expectedPeriodic);
   7.130 +        int actualYoung = result.split("Young regions").length - 1;
   7.131 +        int actualHumonguous = result.split("Humonguous regions").length - 1;
   7.132 +        int actualFree = result.split("Free regions").length - 1;
   7.133 +        int actualOther = result.split("Old regions").length - 1;
   7.134 +
   7.135 +        // the strings we check for above are printed four times per summary
   7.136 +        int expectedPerRegionTypeInfo = (expectedCumulative + expectedPeriodic) * 4;
   7.137 +
   7.138 +        checkCounts(expectedPerRegionTypeInfo, actualYoung, "Young");
   7.139 +        checkCounts(expectedPerRegionTypeInfo, actualHumonguous, "Humonguous");
   7.140 +        checkCounts(expectedPerRegionTypeInfo, actualFree, "Free");
   7.141 +        checkCounts(expectedPerRegionTypeInfo, actualOther, "Old");
   7.142 +    }
   7.143 +
   7.144 +    public static void expectRSetSummaries(String result, int expectedCumulative, int expectedPeriodic) throws Exception {
   7.145 +        int actualTotal = result.split("concurrent refinement").length - 1;
   7.146 +        int actualCumulative = result.split("Cumulative RS summary").length - 1;
   7.147 +
   7.148 +        if (expectedCumulative != actualCumulative) {
   7.149 +            throw new Exception("Incorrect amount of RSet summaries at the end. Expected " + expectedCumulative + ", got " + actualCumulative);
   7.150 +        }
   7.151 +
   7.152 +        if (expectedPeriodic != (actualTotal - actualCumulative)) {
   7.153 +            throw new Exception("Incorrect amount of per-period RSet summaries at the end. Expected " + expectedPeriodic + ", got " + (actualTotal - actualCumulative));
   7.154 +        }
   7.155 +    }
   7.156 +}
   7.157 +

mercurial