diff --git a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp
index 408018f3026..10f719e313a 100644
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp
@@ -3504,6 +3504,13 @@ G1HeapSummary G1CollectedHeap::create_g1_heap_summary() {
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 @@ void G1CollectedHeap::evacuate_collection_set(EvacuationInfo& evacuation_info) {
_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 @@ void G1CollectedHeap::evacuate_collection_set(EvacuationInfo& evacuation_info) {
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,
diff --git a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp
index b32358e1094..ba58ac099c7 100644
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp
@@ -791,6 +791,9 @@ protected:
// 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 @@ public:
const VerifyOption vo) const;
G1HeapSummary create_g1_heap_summary();
+ G1EvacSummary create_g1_evac_summary(G1EvacStats* stats);
// Printing
diff --git a/hotspot/src/share/vm/gc/shared/gcHeapSummary.hpp b/hotspot/src/share/vm/gc/shared/gcHeapSummary.hpp
index a3e26fa2112..8beba465c69 100644
--- a/hotspot/src/share/vm/gc/shared/gcHeapSummary.hpp
+++ b/hotspot/src/share/vm/gc/shared/gcHeapSummary.hpp
@@ -189,4 +189,44 @@ class MetaspaceSummary : public StackObj {
};
+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
diff --git a/hotspot/src/share/vm/gc/shared/gcTrace.cpp b/hotspot/src/share/vm/gc/shared/gcTrace.cpp
index 3edb8846741..982767f6c5d 100644
--- a/hotspot/src/share/vm/gc/shared/gcTrace.cpp
+++ b/hotspot/src/share/vm/gc/shared/gcTrace.cpp
@@ -252,4 +252,12 @@ void G1NewTracer::report_evacuation_failed(EvacuationFailedInfo& ef_info) {
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
diff --git a/hotspot/src/share/vm/gc/shared/gcTrace.hpp b/hotspot/src/share/vm/gc/shared/gcTrace.hpp
index cc23b0efefb..98a171731eb 100644
--- a/hotspot/src/share/vm/gc/shared/gcTrace.hpp
+++ b/hotspot/src/share/vm/gc/shared/gcTrace.hpp
@@ -45,6 +45,7 @@ class MetaspaceChunkFreeListSummary;
class MetaspaceSummary;
class PSHeapSummary;
class G1HeapSummary;
+class G1EvacSummary;
class ReferenceProcessorStats;
class TimePartitions;
class BoolObjectClosure;
@@ -257,10 +258,14 @@ class G1NewTracer : public YoungGCTracer {
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
diff --git a/hotspot/src/share/vm/gc/shared/gcTraceSend.cpp b/hotspot/src/share/vm/gc/shared/gcTraceSend.cpp
index 6c0c3cd651b..04cbbfdf34d 100644
--- a/hotspot/src/share/vm/gc/shared/gcTraceSend.cpp
+++ b/hotspot/src/share/vm/gc/shared/gcTraceSend.cpp
@@ -234,6 +234,37 @@ void G1NewTracer::send_evacuation_failed_event(const EvacuationFailedInfo& ef_in
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) {
diff --git a/hotspot/src/share/vm/trace/trace.xml b/hotspot/src/share/vm/trace/trace.xml
index 574e61618ac..0329d9b725a 100644
--- a/hotspot/src/share/vm/trace/trace.xml
+++ b/hotspot/src/share/vm/trace/trace.xml
@@ -346,6 +346,29 @@ Declares a structure type that can be used in other events.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+