8133530: Add JFR event for evacuation statistics
Summary: Introduce two new JFR events for young/old generation allocation statistics based on previous changes.
Reviewed-by: ehelin, mgerdin
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Wed Aug 19 13:59:39 2015 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Thu Aug 20 15:17:41 2015 +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,
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp Wed Aug 19 13:59:39 2015 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp Thu Aug 20 15:17:41 2015 +0200
@@ -791,6 +791,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
--- a/hotspot/src/share/vm/gc/shared/gcHeapSummary.hpp Wed Aug 19 13:59:39 2015 +0200
+++ b/hotspot/src/share/vm/gc/shared/gcHeapSummary.hpp Thu Aug 20 15:17:41 2015 +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
--- a/hotspot/src/share/vm/gc/shared/gcTrace.cpp Wed Aug 19 13:59:39 2015 +0200
+++ b/hotspot/src/share/vm/gc/shared/gcTrace.cpp Thu Aug 20 15:17:41 2015 +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
--- a/hotspot/src/share/vm/gc/shared/gcTrace.hpp Wed Aug 19 13:59:39 2015 +0200
+++ b/hotspot/src/share/vm/gc/shared/gcTrace.hpp Thu Aug 20 15:17:41 2015 +0200
@@ -45,6 +45,7 @@
class MetaspaceSummary;
class PSHeapSummary;
class G1HeapSummary;
+class G1EvacSummary;
class ReferenceProcessorStats;
class TimePartitions;
class BoolObjectClosure;
@@ -257,10 +258,14 @@
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;
};
#endif
--- a/hotspot/src/share/vm/gc/shared/gcTraceSend.cpp Wed Aug 19 13:59:39 2015 +0200
+++ b/hotspot/src/share/vm/gc/shared/gcTraceSend.cpp Thu Aug 20 15:17:41 2015 +0200
@@ -234,6 +234,37 @@
e.commit();
}
}
+
+static TraceStructG1EvacStats create_g1_evacstats(unsigned gcid, const G1EvacSummary& summary) {
+ TraceStructG1EvacStats s;
+ s.set_gcId(gcid);
+ 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;
+}
+
+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(_shared_gc_info.gc_id().id(), 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(_shared_gc_info.gc_id().id(), summary));
+ old_evt.commit();
+ }
+}
#endif
static TraceStructVirtualSpace to_trace_struct(const VirtualSpaceSummary& summary) {
--- a/hotspot/src/share/vm/trace/trace.xml Wed Aug 19 13:59:39 2015 +0200
+++ b/hotspot/src/share/vm/trace/trace.xml Thu Aug 20 15:17:41 2015 +0200
@@ -346,6 +346,29 @@
<value type="BYTES64" field="totalSize" label="Total Size" />
</event>
+ <struct id="G1EvacStats">
+ <value type="UINT" field="gcId" label="GC ID" relation="GC_ID"/>
+ <value type="BYTES64" field="allocated" label="Allocated" description="Total memory allocated by PLABs"/>
+ <value type="BYTES64" field="wasted" label="Wasted" description="Total memory wasted within PLABs due to alignment or refill"/>
+ <value type="BYTES64" field="used" label="Used" description="Total memory occupied by objects within PLABs"/>
+ <value type="BYTES64" field="undoWaste" label="Undo Wasted" description="Total memory wasted due to allocation undo within PLABs"/>
+ <value type="BYTES64" field="regionEndWaste" label="Region End Wasted" description="Total memory wasted at the end of regions due to refill"/>
+ <value type="UINT" field="regionsRefilled" label="Region Refills" description="Total memory wasted at the end of regions due to refill"/>
+ <value type="BYTES64" field="directAllocated" label="Allocated (direct)" description="Total memory allocated using direct allocation outside of PLABs"/>
+ <value type="BYTES64" field="failureUsed" label="Used (failure)" description="Total memory occupied by objects in regions where evacuation failed"/>
+ <value type="BYTES64" field="failureWaste" label="Wasted (failure)" description="Total memory left unused in regions where evacuation failed"/>
+ </struct>
+
+ <event id="GCG1EvacuationYoungStatistics" path="vm/gc/detailed/g1_evac_young_stats" label="G1 Evacuation Statistics for Young" is_instant="true"
+ description="Memory related evacuation statistics during GC for the young generation">
+ <structvalue type="G1EvacStats" field="stats" label="Evacuation statistics"/>
+ </event>
+
+ <event id="GCG1EvacuationOldStatistics" path="vm/gc/detailed/g1_evac_old_stats" label="G1 Evacuation Memory Statistics for Old" is_instant="true"
+ description="Memory related evacuation statistics during GC for the old generation">
+ <structvalue type="G1EvacStats" field="stats" label="Evacuation statistics"/>
+ </event>
+
<!-- Promotion events, Supported GCs are Parallel Scavange, G1 and CMS with Parallel New. -->
<event id="PromoteObjectInNewPLAB" path="vm/gc/detailed/object_promotion_in_new_PLAB" label="Promotion in new PLAB"
description="Object survived scavenge and was copied to a new Promotion Local Allocation Buffer (PLAB). Supported GCs are Parallel Scavange, G1 and CMS with Parallel New. Due to promotion being done in parallel an object might be reported multiple times as the GC threads race to copy all objects."