--- old/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp 2013-05-16 16:29:30.308224484 +0200 +++ new/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp 2013-05-16 16:29:30.140224490 +0200 @@ -3536,15 +3536,22 @@ AllocationProfiler::iterate_since_last_gc(); // Fill TLAB's and such ensure_parsability(true); + + if (G1SummarizeRSetStats && + (G1SummarizeRSetStatsPeriod > 0) && ((G1SummarizeRSetStatsTime & 2) != 0) && + // we are at the end of the GC. Total collections has already been increased. + (total_collections() % G1SummarizeRSetStatsPeriod == 0)) { + g1_rem_set()->print_periodic_summary_info("Before GC RS summary"); + } } void G1CollectedHeap::gc_epilogue(bool full /* Ignored */) { if (G1SummarizeRSetStats && - (G1SummarizeRSetStatsPeriod > 0) && + (G1SummarizeRSetStatsPeriod > 0) && ((G1SummarizeRSetStatsTime & 1) != 0) && // we are at the end of the GC. Total collections has already been increased. ((total_collections() - 1) % G1SummarizeRSetStatsPeriod == 0)) { - g1_rem_set()->print_periodic_summary_info(); + g1_rem_set()->print_periodic_summary_info("After GC RS summary"); } // FIXME: what is this about? --- old/src/share/vm/gc_implementation/g1/g1RemSet.cpp 2013-05-16 16:29:31.624224443 +0200 +++ new/src/share/vm/gc_implementation/g1/g1RemSet.cpp 2013-05-16 16:29:31.424224449 +0200 @@ -700,12 +700,12 @@ return has_refs_into_cset; } -void G1RemSet::print_periodic_summary_info() { +void G1RemSet::print_periodic_summary_info(const char * header) { G1RemSetSummary current; current.initialize(this, n_workers()); _last_period_summary.subtract_from(¤t); - print_summary_info(&_last_period_summary); + print_summary_info(&_last_period_summary, header); _last_period_summary.set(¤t); } --- old/src/share/vm/gc_implementation/g1/g1RemSet.hpp 2013-05-16 16:29:32.920224402 +0200 +++ new/src/share/vm/gc_implementation/g1/g1RemSet.hpp 2013-05-16 16:29:32.596224412 +0200 @@ -133,7 +133,7 @@ virtual void print_summary_info(); // Print accumulated summary info from the last time called. - virtual void print_periodic_summary_info(); + virtual void print_periodic_summary_info(const char * header); // Prepare remembered set for verification. virtual void prepare_for_verify(); --- old/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp 2013-05-16 16:29:34.632224349 +0200 +++ new/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp 2013-05-16 16:29:34.428224355 +0200 @@ -126,16 +126,75 @@ } class HRRSStatsIter: public HeapRegionClosure { - size_t _occupied; - size_t _total_mem_sz; - size_t _max_mem_sz; - HeapRegion* _max_mem_sz_region; +private: + size_t _max_mem_sz; + HeapRegion* _max_mem_sz_region; +public: + struct region_type_counter_t { + private: + size_t _mem_size; + size_t _occupied; + size_t _amount; + + static double percent_of(size_t* value, size_t total) { + if (total != 0) { + return ((double)*value / total) * 100.0f; + } else { + return 0.0f; + } + } + + double mem_size_percent_of(size_t total) { + return percent_of(&_mem_size, total); + } + + double occupied_percent_of(size_t total) { + return percent_of(&_occupied, total); + } + + size_t amount() const { + return _amount; + } + + public: + + region_type_counter_t() : _mem_size(0), _occupied(0), _amount(0) { + } + + void add(size_t mem_size, size_t occupied) { + _mem_size += mem_size; + _occupied += occupied; + _amount++; + } + + size_t mem_size() const { + return _mem_size; + } + + size_t occupied() const { + return _occupied; + } + + void print_mem_info_on(outputStream * out, size_t total, char const * type) { + out->print_cr(" %8dK (%5.1f%%) by %zd %s regions", mem_size()/K, mem_size_percent_of(total), amount(), type); + } + + void print_occupied_info_on(outputStream * out, size_t total, char const * type) { + out->print_cr(" %8d (%5.1f%%) entries by %zd %s regions", occupied(), occupied_percent_of(total), amount(), type); + } + }; + +private: + region_type_counter_t _young; + region_type_counter_t _humonguous; + region_type_counter_t _free; + region_type_counter_t _other; + region_type_counter_t _all; + public: HRRSStatsIter() : - _occupied(0), - _total_mem_sz(0), - _max_mem_sz(0), - _max_mem_sz_region(NULL) + _max_mem_sz(0), _max_mem_sz_region(NULL), + _all(), _young(), _humonguous(), _free(), _other() {} bool doHeapRegion(HeapRegion* r) { @@ -144,14 +203,41 @@ _max_mem_sz = mem_sz; _max_mem_sz_region = r; } - _total_mem_sz += mem_sz; size_t occ = r->rem_set()->occupied(); - _occupied += occ; + + _all.add(mem_sz, occ); + if (r->is_young()) { + _young.add(mem_sz, occ); + } else if (r->isHumongous()) { + _humonguous.add(mem_sz, occ); + } else if (r->is_empty()) { + _free.add(mem_sz, occ); + } else { + _other.add(mem_sz, occ); + } + return false; } - size_t total_mem_sz() { return _total_mem_sz; } + + region_type_counter_t& young() { + return _young; + } + + region_type_counter_t& humonguous() { + return _humonguous; + } + + region_type_counter_t& free() { + return _free; + } + + region_type_counter_t& other() { + return _other; + } + + size_t total_mem_sz() { return _all.mem_size(); } size_t max_mem_sz() { return _max_mem_sz; } - size_t occupied() { return _occupied; } + size_t occupied() { return _all.occupied(); } HeapRegion* max_mem_sz_region() { return _max_mem_sz_region; } }; @@ -187,12 +273,20 @@ out->print_cr(" Total heap region rem set sizes = "SIZE_FORMAT"K." " Max = "SIZE_FORMAT"K.", blk.total_mem_sz()/K, blk.max_mem_sz()/K); + blk.young().print_mem_info_on(out, blk.total_mem_sz(), "Young"); + blk.humonguous().print_mem_info_on(out, blk.total_mem_sz(), "Humonguous"); + blk.free().print_mem_info_on(out, blk.total_mem_sz(), "Free"); + blk.other().print_mem_info_on(out, blk.total_mem_sz(), "Other"); out->print_cr(" Static structures = "SIZE_FORMAT"K," " free_lists = "SIZE_FORMAT"K.", HeapRegionRemSet::static_mem_size() / K, HeapRegionRemSet::fl_mem_size() / K); out->print_cr(" "SIZE_FORMAT" occupied cards represented.", blk.occupied()); + blk.young().print_occupied_info_on(out, blk.occupied(), "Young"); + blk.humonguous().print_occupied_info_on(out, blk.occupied(), "Humonguous"); + blk.free().print_occupied_info_on(out, blk.occupied(), "Free"); + blk.other().print_occupied_info_on(out, blk.occupied(), "Other"); HeapRegion* max_mem_sz_region = blk.max_mem_sz_region(); HeapRegionRemSet* rem_set = max_mem_sz_region->rem_set(); out->print_cr(" Max size region = "HR_FORMAT", " --- old/src/share/vm/gc_implementation/g1/g1_globals.hpp 2013-05-16 16:29:35.688224315 +0200 +++ new/src/share/vm/gc_implementation/g1/g1_globals.hpp 2013-05-16 16:29:35.464224323 +0200 @@ -62,7 +62,11 @@ diagnostic(bool, G1SummarizeRSetStats, false, \ "Summarize remembered set processing info") \ \ - diagnostic(intx, G1SummarizeRSetStatsPeriod, 0, \ + diagnostic(uintx, G1SummarizeRSetStatsTime, 1, \ + "The time at which remembered set summary statistics are " \ + "printed. (1 = end of GC, 2 = start of GC, 3 = both).") \ + \ + diagnostic(uintx, G1SummarizeRSetStatsPeriod, 0, \ "The period (in number of GCs) at which we will generate " \ "update buffer processing info " \ "(0 means do not periodically generate this info); " \ --- old/src/share/vm/runtime/arguments.cpp 2013-05-16 16:29:36.924224277 +0200 +++ new/src/share/vm/runtime/arguments.cpp 2013-05-16 16:29:36.692224284 +0200 @@ -2053,6 +2053,8 @@ "G1ConcRSHotCardLimit"); status = status && verify_interval(G1ConcRSLogCacheSize, 0, 31, "G1ConcRSLogCacheSize"); + status = status && verify_interval(G1SummarizeRSetStatsTime, 1, 3, + "G1SummarizeRSetStatsTime"); } if (UseConcMarkSweepGC) { status = status && verify_min_value(CMSOldPLABNumRefills, 1, "CMSOldPLABNumRefills");