--- old/src/share/vm/gc/g1/g1CollectedHeap.cpp 2015-08-17 12:55:16.012057962 +0200 +++ new/src/share/vm/gc/g1/g1CollectedHeap.cpp 2015-08-17 12:55:15.931055536 +0200 @@ -3504,6 +3504,13 @@ return G1HeapSummary(heap_summary, used(), eden_used_bytes, eden_capacity_bytes, survivor_used_bytes); } +G1EvacSummary G1CollectedHeap::create_g1_evac_summary(G1EvacStats* stats) { + return G1EvacSummary(stats->allocated(), stats->wasted(), stats->undo_wasted(), + stats->unused(), stats->used(), stats->region_end_waste(), + stats->regions_filled(), stats->direct_allocated(), + stats->failure_used(), stats->failure_waste()); +} + void G1CollectedHeap::trace_heap(GCWhen::Type when, const GCTracer* gc_tracer) { const G1HeapSummary& heap_summary = create_g1_heap_summary(); gc_tracer->report_gc_heap_summary(when, heap_summary); @@ -5544,6 +5551,8 @@ _allocator->release_gc_alloc_regions(evacuation_info); g1_rem_set()->cleanup_after_oops_into_collection_set_do(); + record_obj_copy_mem_stats(); + // Reset and re-enable the hot card cache. // Note the counts for the cards in the regions in the // collection set are reset when the collection set is freed. @@ -5574,6 +5583,11 @@ COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); } +void G1CollectedHeap::record_obj_copy_mem_stats() { + _gc_tracer_stw->report_evacuation_statistics(create_g1_evac_summary(&_survivor_evac_stats), + create_g1_evac_summary(&_old_evac_stats)); +} + void G1CollectedHeap::free_region(HeapRegion* hr, FreeRegionList* free_list, bool par, --- old/src/share/vm/gc/g1/g1CollectedHeap.hpp 2015-08-17 12:55:16.530073473 +0200 +++ new/src/share/vm/gc/g1/g1CollectedHeap.hpp 2015-08-17 12:55:16.452071137 +0200 @@ -790,6 +790,9 @@ // Actually do the work of evacuating the collection set. void evacuate_collection_set(EvacuationInfo& evacuation_info); + + // Update object copying statistics. + void record_obj_copy_mem_stats(); // The g1 remembered set of the heap. G1RemSet* _g1_rem_set; @@ -1566,6 +1569,7 @@ const VerifyOption vo) const; G1HeapSummary create_g1_heap_summary(); + G1EvacSummary create_g1_evac_summary(G1EvacStats* stats); // Printing --- old/src/share/vm/gc/shared/gcHeapSummary.hpp 2015-08-17 12:55:16.989087217 +0200 +++ new/src/share/vm/gc/shared/gcHeapSummary.hpp 2015-08-17 12:55:16.912084911 +0200 @@ -189,4 +189,44 @@ }; +class G1EvacSummary : public StackObj { +private: + size_t _allocated; // Total allocated + size_t _wasted; // of which wasted (internal fragmentation) + size_t _undo_wasted; // of which wasted on undo (is not used for calculation of PLAB size) + size_t _unused; // Unused in last buffer + size_t _used; + + size_t _region_end_waste; // Number of words wasted due to skipping to the next region. + uint _regions_filled; // Number of regions filled completely. + size_t _direct_allocated; // Number of words allocated directly into the regions. + + // Number of words in live objects remaining in regions that ultimately suffered an + // evacuation failure. This is used in the regions when the regions are made old regions. + size_t _failure_used; + // Number of words wasted in regions which failed evacuation. This is the sum of space + // for objects successfully copied out of the regions (now dead space) plus waste at the + // end of regions. + size_t _failure_waste; +public: + G1EvacSummary(size_t allocated, size_t wasted, size_t undo_wasted, size_t unused, + size_t used, size_t region_end_waste, uint regions_filled, size_t direct_allocated, + size_t failure_used, size_t failure_waste) : + _allocated(allocated), _wasted(wasted), _undo_wasted(undo_wasted), _unused(unused), + _used(used), _region_end_waste(region_end_waste), _regions_filled(regions_filled), + _direct_allocated(direct_allocated), _failure_used(failure_used), _failure_waste(failure_waste) + { } + + size_t allocated() const { return _allocated; } + size_t wasted() const { return _wasted; } + size_t undo_wasted() const { return _undo_wasted; } + size_t unused() const { return _unused; } + size_t used() const { return _used; } + size_t region_end_waste() const { return _region_end_waste; } + uint regions_filled() const { return _regions_filled; } + size_t direct_allocated() const { return _direct_allocated; } + size_t failure_used() const { return _failure_used; } + size_t failure_waste() const { return _failure_waste; } +}; + #endif // SHARE_VM_GC_SHARED_GCHEAPSUMMARY_HPP --- old/src/share/vm/gc/shared/gcTrace.cpp 2015-08-17 12:55:17.427100333 +0200 +++ new/src/share/vm/gc/shared/gcTrace.cpp 2015-08-17 12:55:17.350098027 +0200 @@ -252,4 +252,12 @@ send_evacuation_failed_event(ef_info); ef_info.reset(); } + +void G1NewTracer::report_evacuation_statistics(const G1EvacSummary& young_summary, const G1EvacSummary& old_summary) const { + assert_set_gc_id(); + + send_young_evacuation_statistics(young_summary); + send_old_evacuation_statistics(old_summary); +} + #endif --- old/src/share/vm/gc/shared/gcTrace.hpp 2015-08-17 12:55:17.870113598 +0200 +++ new/src/share/vm/gc/shared/gcTrace.hpp 2015-08-17 12:55:17.791111232 +0200 @@ -37,6 +37,7 @@ #include "utilities/ticks.hpp" #if INCLUDE_ALL_GCS #include "gc/g1/g1YCTypes.hpp" +#include "gc/shared/gcHeapSummary.hpp" #endif class EvacuationInfo; @@ -45,6 +46,7 @@ class MetaspaceSummary; class PSHeapSummary; class G1HeapSummary; +struct TraceStructG1EvacStats; class ReferenceProcessorStats; class TimePartitions; class BoolObjectClosure; @@ -257,10 +259,16 @@ void report_evacuation_info(EvacuationInfo* info); void report_evacuation_failed(EvacuationFailedInfo& ef_info); + void report_evacuation_statistics(const G1EvacSummary& young_summary, const G1EvacSummary& old_summary) const; private: void send_g1_young_gc_event(); void send_evacuation_info_event(EvacuationInfo* info); void send_evacuation_failed_event(const EvacuationFailedInfo& ef_info) const; + + void send_young_evacuation_statistics(const G1EvacSummary& summary) const; + void send_old_evacuation_statistics(const G1EvacSummary& summary) const; + + TraceStructG1EvacStats create_g1_evacstats(const G1EvacSummary& summary) const; }; #endif --- old/src/share/vm/gc/shared/gcTraceSend.cpp 2015-08-17 12:55:18.319127043 +0200 +++ new/src/share/vm/gc/shared/gcTraceSend.cpp 2015-08-17 12:55:18.240124677 +0200 @@ -234,6 +234,37 @@ e.commit(); } } + +void G1NewTracer::send_young_evacuation_statistics(const G1EvacSummary& summary) const { + EventGCG1EvacuationYoungStatistics surv_evt; + if (surv_evt.should_commit()) { + surv_evt.set_stats(create_g1_evacstats(summary)); + surv_evt.commit(); + } +} + +void G1NewTracer::send_old_evacuation_statistics(const G1EvacSummary& summary) const { + EventGCG1EvacuationOldStatistics old_evt; + if (old_evt.should_commit()) { + old_evt.set_stats(create_g1_evacstats(summary)); + old_evt.commit(); + } +} + +TraceStructG1EvacStats G1NewTracer::create_g1_evacstats(const G1EvacSummary& summary) const { + TraceStructG1EvacStats s; + s.set_gcId(_shared_gc_info.gc_id().id()); + s.set_allocated(summary.allocated() * HeapWordSize); + s.set_wasted(summary.wasted() * HeapWordSize); + s.set_used(summary.used() * HeapWordSize); + s.set_undoWaste(summary.undo_wasted() * HeapWordSize); + s.set_regionEndWaste(summary.region_end_waste() * HeapWordSize); + s.set_regionsRefilled(summary.regions_filled()); + s.set_directAllocated(summary.direct_allocated() * HeapWordSize); + s.set_failureUsed(summary.failure_used() * HeapWordSize); + s.set_failureWaste(summary.failure_waste() * HeapWordSize); + return s; +} #endif static TraceStructVirtualSpace to_trace_struct(const VirtualSpaceSummary& summary) { --- old/src/share/vm/trace/trace.xml 2015-08-17 12:55:18.765140398 +0200 +++ new/src/share/vm/trace/trace.xml 2015-08-17 12:55:18.685138002 +0200 @@ -346,6 +346,29 @@ + + + + + + + + + + + + + + + + + + + + +