8036703: Add trace event with statistics for the metaspace chunk free lists
Reviewed-by: stefank, mgerdin, coleenp, egahlin
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Tue Mar 18 08:00:21 2014 +0100
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Tue Mar 18 09:03:28 2014 +0100
@@ -2496,7 +2496,8 @@
}
void CMSCollector::report_heap_summary(GCWhen::Type when) {
- _gc_tracer_cm->report_gc_heap_summary(when, _last_heap_summary, _last_metaspace_summary);
+ _gc_tracer_cm->report_gc_heap_summary(when, _last_heap_summary);
+ _gc_tracer_cm->report_metaspace_summary(when, _last_metaspace_summary);
}
void CMSCollector::collect_in_foreground(bool clear_all_soft_refs, GCCause::Cause cause) {
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp Tue Mar 18 08:00:21 2014 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp Tue Mar 18 09:03:28 2014 +0100
@@ -665,8 +665,10 @@
void ParallelScavengeHeap::trace_heap(GCWhen::Type when, GCTracer* gc_tracer) {
const PSHeapSummary& heap_summary = create_ps_heap_summary();
+ gc_tracer->report_gc_heap_summary(when, heap_summary);
+
const MetaspaceSummary& metaspace_summary = create_metaspace_summary();
- gc_tracer->report_gc_heap_summary(when, heap_summary, metaspace_summary);
+ gc_tracer->report_metaspace_summary(when, metaspace_summary);
}
ParallelScavengeHeap* ParallelScavengeHeap::heap() {
--- a/hotspot/src/share/vm/gc_implementation/shared/gcHeapSummary.hpp Tue Mar 18 08:00:21 2014 +0100
+++ b/hotspot/src/share/vm/gc_implementation/shared/gcHeapSummary.hpp Tue Mar 18 09:03:28 2014 +0100
@@ -26,6 +26,7 @@
#define SHARE_VM_GC_IMPLEMENTATION_SHARED_GCHEAPSUMMARY_HPP
#include "memory/allocation.hpp"
+#include "memory/metaspaceChunkFreeListSummary.hpp"
class VirtualSpaceSummary : public StackObj {
HeapWord* _start;
@@ -129,16 +130,45 @@
MetaspaceSizes _meta_space;
MetaspaceSizes _data_space;
MetaspaceSizes _class_space;
+ MetaspaceChunkFreeListSummary _metaspace_chunk_free_list_summary;
+ MetaspaceChunkFreeListSummary _class_chunk_free_list_summary;
public:
- MetaspaceSummary() : _capacity_until_GC(0), _meta_space(), _data_space(), _class_space() {}
- MetaspaceSummary(size_t capacity_until_GC, const MetaspaceSizes& meta_space, const MetaspaceSizes& data_space, const MetaspaceSizes& class_space) :
- _capacity_until_GC(capacity_until_GC), _meta_space(meta_space), _data_space(data_space), _class_space(class_space) { }
+ MetaspaceSummary() :
+ _capacity_until_GC(0),
+ _meta_space(),
+ _data_space(),
+ _class_space(),
+ _metaspace_chunk_free_list_summary(),
+ _class_chunk_free_list_summary()
+ {}
+ MetaspaceSummary(size_t capacity_until_GC,
+ const MetaspaceSizes& meta_space,
+ const MetaspaceSizes& data_space,
+ const MetaspaceSizes& class_space,
+ const MetaspaceChunkFreeListSummary& metaspace_chunk_free_list_summary,
+ const MetaspaceChunkFreeListSummary& class_chunk_free_list_summary) :
+ _capacity_until_GC(capacity_until_GC),
+ _meta_space(meta_space),
+ _data_space(data_space),
+ _class_space(class_space),
+ _metaspace_chunk_free_list_summary(metaspace_chunk_free_list_summary),
+ _class_chunk_free_list_summary(class_chunk_free_list_summary)
+ {}
size_t capacity_until_GC() const { return _capacity_until_GC; }
const MetaspaceSizes& meta_space() const { return _meta_space; }
const MetaspaceSizes& data_space() const { return _data_space; }
const MetaspaceSizes& class_space() const { return _class_space; }
+
+ const MetaspaceChunkFreeListSummary& metaspace_chunk_free_list_summary() const {
+ return _metaspace_chunk_free_list_summary;
+ }
+
+ const MetaspaceChunkFreeListSummary& class_chunk_free_list_summary() const {
+ return _class_chunk_free_list_summary;
+ }
+
};
#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_GCHEAPSUMMARY_HPP
--- a/hotspot/src/share/vm/gc_implementation/shared/gcTrace.cpp Tue Mar 18 08:00:21 2014 +0100
+++ b/hotspot/src/share/vm/gc_implementation/shared/gcTrace.cpp Tue Mar 18 09:03:28 2014 +0100
@@ -139,11 +139,21 @@
}
#endif // INCLUDE_SERVICES
-void GCTracer::report_gc_heap_summary(GCWhen::Type when, const GCHeapSummary& heap_summary, const MetaspaceSummary& meta_space_summary) const {
+void GCTracer::report_gc_heap_summary(GCWhen::Type when, const GCHeapSummary& heap_summary) const {
assert_set_gc_id();
send_gc_heap_summary_event(when, heap_summary);
- send_meta_space_summary_event(when, meta_space_summary);
+}
+
+void GCTracer::report_metaspace_summary(GCWhen::Type when, const MetaspaceSummary& summary) const {
+ assert_set_gc_id();
+
+ send_meta_space_summary_event(when, summary);
+
+ send_metaspace_chunk_free_list_summary(when, Metaspace::NonClassType, summary.metaspace_chunk_free_list_summary());
+ if (UseCompressedClassPointers) {
+ send_metaspace_chunk_free_list_summary(when, Metaspace::ClassType, summary.class_chunk_free_list_summary());
+ }
}
void YoungGCTracer::report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions) {
--- a/hotspot/src/share/vm/gc_implementation/shared/gcTrace.hpp Tue Mar 18 08:00:21 2014 +0100
+++ b/hotspot/src/share/vm/gc_implementation/shared/gcTrace.hpp Tue Mar 18 09:03:28 2014 +0100
@@ -30,6 +30,7 @@
#include "gc_implementation/shared/gcWhen.hpp"
#include "gc_implementation/shared/copyFailedInfo.hpp"
#include "memory/allocation.hpp"
+#include "memory/metaspace.hpp"
#include "memory/referenceType.hpp"
#if INCLUDE_ALL_GCS
#include "gc_implementation/g1/g1YCTypes.hpp"
@@ -41,6 +42,7 @@
class EvacuationInfo;
class GCHeapSummary;
+class MetaspaceChunkFreeListSummary;
class MetaspaceSummary;
class PSHeapSummary;
class ReferenceProcessorStats;
@@ -124,7 +126,8 @@
public:
void report_gc_start(GCCause::Cause cause, const Ticks& timestamp);
void report_gc_end(const Ticks& timestamp, TimePartitions* time_partitions);
- void report_gc_heap_summary(GCWhen::Type when, const GCHeapSummary& heap_summary, const MetaspaceSummary& meta_space_summary) const;
+ void report_gc_heap_summary(GCWhen::Type when, const GCHeapSummary& heap_summary) const;
+ void report_metaspace_summary(GCWhen::Type when, const MetaspaceSummary& metaspace_summary) const;
void report_gc_reference_stats(const ReferenceProcessorStats& rp) const;
void report_object_count_after_gc(BoolObjectClosure* object_filter) NOT_SERVICES_RETURN;
bool has_reported_gc_start() const;
@@ -138,6 +141,7 @@
void send_garbage_collection_event() const;
void send_gc_heap_summary_event(GCWhen::Type when, const GCHeapSummary& heap_summary) const;
void send_meta_space_summary_event(GCWhen::Type when, const MetaspaceSummary& meta_space_summary) const;
+ void send_metaspace_chunk_free_list_summary(GCWhen::Type when, Metaspace::MetadataType mdtype, const MetaspaceChunkFreeListSummary& summary) const;
void send_reference_stats_event(ReferenceType type, size_t count) const;
void send_phase_events(TimePartitions* time_partitions) const;
};
--- a/hotspot/src/share/vm/gc_implementation/shared/gcTraceSend.cpp Tue Mar 18 08:00:21 2014 +0100
+++ b/hotspot/src/share/vm/gc_implementation/shared/gcTraceSend.cpp Tue Mar 18 09:03:28 2014 +0100
@@ -64,6 +64,30 @@
}
}
+void GCTracer::send_metaspace_chunk_free_list_summary(GCWhen::Type when, Metaspace::MetadataType mdtype,
+ const MetaspaceChunkFreeListSummary& summary) const {
+ EventMetaspaceChunkFreeListSummary e;
+ if (e.should_commit()) {
+ e.set_gcId(_shared_gc_info.id());
+ e.set_when(when);
+ e.set_metadataType(mdtype);
+
+ e.set_specializedChunks(summary.num_specialized_chunks());
+ e.set_specializedChunksTotalSize(summary.specialized_chunks_size_in_bytes());
+
+ e.set_smallChunks(summary.num_small_chunks());
+ e.set_smallChunksTotalSize(summary.small_chunks_size_in_bytes());
+
+ e.set_mediumChunks(summary.num_medium_chunks());
+ e.set_mediumChunksTotalSize(summary.medium_chunks_size_in_bytes());
+
+ e.set_humongousChunks(summary.num_humongous_chunks());
+ e.set_humongousChunksTotalSize(summary.humongous_chunks_size_in_bytes());
+
+ e.commit();
+ }
+}
+
void ParallelOldTracer::send_parallel_old_event() const {
EventGCParallelOld e(UNTIMED);
if (e.should_commit()) {
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp Tue Mar 18 08:00:21 2014 +0100
+++ b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp Tue Mar 18 09:03:28 2014 +0100
@@ -97,7 +97,13 @@
MetaspaceAux::allocated_used_bytes(Metaspace::ClassType),
MetaspaceAux::reserved_bytes(Metaspace::ClassType));
- return MetaspaceSummary(MetaspaceGC::capacity_until_GC(), meta_space, data_space, class_space);
+ const MetaspaceChunkFreeListSummary& ms_chunk_free_list_summary =
+ MetaspaceAux::chunk_free_list_summary(Metaspace::NonClassType);
+ const MetaspaceChunkFreeListSummary& class_chunk_free_list_summary =
+ MetaspaceAux::chunk_free_list_summary(Metaspace::ClassType);
+
+ return MetaspaceSummary(MetaspaceGC::capacity_until_GC(), meta_space, data_space, class_space,
+ ms_chunk_free_list_summary, class_chunk_free_list_summary);
}
void CollectedHeap::print_heap_before_gc() {
@@ -128,8 +134,10 @@
void CollectedHeap::trace_heap(GCWhen::Type when, GCTracer* gc_tracer) {
const GCHeapSummary& heap_summary = create_heap_summary();
+ gc_tracer->report_gc_heap_summary(when, heap_summary);
+
const MetaspaceSummary& metaspace_summary = create_metaspace_summary();
- gc_tracer->report_gc_heap_summary(when, heap_summary, metaspace_summary);
+ gc_tracer->report_metaspace_summary(when, metaspace_summary);
}
void CollectedHeap::trace_heap_before_gc(GCTracer* gc_tracer) {
--- a/hotspot/src/share/vm/memory/metaspace.cpp Tue Mar 18 08:00:21 2014 +0100
+++ b/hotspot/src/share/vm/memory/metaspace.cpp Tue Mar 18 09:03:28 2014 +0100
@@ -185,6 +185,48 @@
// Remove from a list by size. Selects list based on size of chunk.
Metachunk* free_chunks_get(size_t chunk_word_size);
+#define index_bounds_check(index) \
+ assert(index == SpecializedIndex || \
+ index == SmallIndex || \
+ index == MediumIndex || \
+ index == HumongousIndex, err_msg("Bad index: %d", (int) index))
+
+ size_t num_free_chunks(ChunkIndex index) const {
+ index_bounds_check(index);
+
+ if (index == HumongousIndex) {
+ return _humongous_dictionary.total_free_blocks();
+ }
+
+ ssize_t count = _free_chunks[index].count();
+ return count == -1 ? 0 : (size_t) count;
+ }
+
+ size_t size_free_chunks_in_bytes(ChunkIndex index) const {
+ index_bounds_check(index);
+
+ size_t word_size = 0;
+ if (index == HumongousIndex) {
+ word_size = _humongous_dictionary.total_size();
+ } else {
+ const size_t size_per_chunk_in_words = _free_chunks[index].size();
+ word_size = size_per_chunk_in_words * num_free_chunks(index);
+ }
+
+ return word_size * BytesPerWord;
+ }
+
+ MetaspaceChunkFreeListSummary chunk_free_list_summary() const {
+ return MetaspaceChunkFreeListSummary(num_free_chunks(SpecializedIndex),
+ num_free_chunks(SmallIndex),
+ num_free_chunks(MediumIndex),
+ num_free_chunks(HumongousIndex),
+ size_free_chunks_in_bytes(SpecializedIndex),
+ size_free_chunks_in_bytes(SmallIndex),
+ size_free_chunks_in_bytes(MediumIndex),
+ size_free_chunks_in_bytes(HumongousIndex));
+ }
+
// Debug support
void verify();
void slow_verify() {
@@ -2637,6 +2679,19 @@
return free_chunks_total_words() * BytesPerWord;
}
+bool MetaspaceAux::has_chunk_free_list(Metaspace::MetadataType mdtype) {
+ return Metaspace::get_chunk_manager(mdtype) != NULL;
+}
+
+MetaspaceChunkFreeListSummary MetaspaceAux::chunk_free_list_summary(Metaspace::MetadataType mdtype) {
+ if (!has_chunk_free_list(mdtype)) {
+ return MetaspaceChunkFreeListSummary();
+ }
+
+ const ChunkManager* cm = Metaspace::get_chunk_manager(mdtype);
+ return cm->chunk_free_list_summary();
+}
+
void MetaspaceAux::print_metaspace_change(size_t prev_metadata_used) {
gclog_or_tty->print(", [Metaspace:");
if (PrintGCDetails && Verbose) {
--- a/hotspot/src/share/vm/memory/metaspace.hpp Tue Mar 18 08:00:21 2014 +0100
+++ b/hotspot/src/share/vm/memory/metaspace.hpp Tue Mar 18 09:03:28 2014 +0100
@@ -26,6 +26,7 @@
#include "memory/allocation.hpp"
#include "memory/memRegion.hpp"
+#include "memory/metaspaceChunkFreeListSummary.hpp"
#include "runtime/virtualspace.hpp"
#include "utilities/exceptions.hpp"
@@ -355,6 +356,9 @@
return min_chunk_size_words() * BytesPerWord;
}
+ static bool has_chunk_free_list(Metaspace::MetadataType mdtype);
+ static MetaspaceChunkFreeListSummary chunk_free_list_summary(Metaspace::MetadataType mdtype);
+
// Print change in used metadata.
static void print_metaspace_change(size_t prev_metadata_used);
static void print_on(outputStream * out);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/memory/metaspaceChunkFreeListSummary.hpp Tue Mar 18 09:03:28 2014 +0100
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef SHARE_VM_MEMORY_METASPACE_CHUNK_FREE_LIST_SUMMARY_HPP
+#define SHARE_VM_MEMORY_METASPACE_CHUNK_FREE_LIST_SUMMARY_HPP
+
+#include "memory/allocation.hpp"
+
+class MetaspaceChunkFreeListSummary VALUE_OBJ_CLASS_SPEC {
+ size_t _num_specialized_chunks;
+ size_t _num_small_chunks;
+ size_t _num_medium_chunks;
+ size_t _num_humongous_chunks;
+
+ size_t _specialized_chunks_size_in_bytes;
+ size_t _small_chunks_size_in_bytes;
+ size_t _medium_chunks_size_in_bytes;
+ size_t _humongous_chunks_size_in_bytes;
+
+ public:
+ MetaspaceChunkFreeListSummary() :
+ _num_specialized_chunks(0),
+ _num_small_chunks(0),
+ _num_medium_chunks(0),
+ _num_humongous_chunks(0),
+ _specialized_chunks_size_in_bytes(0),
+ _small_chunks_size_in_bytes(0),
+ _medium_chunks_size_in_bytes(0),
+ _humongous_chunks_size_in_bytes(0)
+ {}
+
+ MetaspaceChunkFreeListSummary(size_t num_specialized_chunks,
+ size_t num_small_chunks,
+ size_t num_medium_chunks,
+ size_t num_humongous_chunks,
+ size_t specialized_chunks_size_in_bytes,
+ size_t small_chunks_size_in_bytes,
+ size_t medium_chunks_size_in_bytes,
+ size_t humongous_chunks_size_in_bytes) :
+ _num_specialized_chunks(num_specialized_chunks),
+ _num_small_chunks(num_small_chunks),
+ _num_medium_chunks(num_medium_chunks),
+ _num_humongous_chunks(num_humongous_chunks),
+ _specialized_chunks_size_in_bytes(specialized_chunks_size_in_bytes),
+ _small_chunks_size_in_bytes(small_chunks_size_in_bytes),
+ _medium_chunks_size_in_bytes(medium_chunks_size_in_bytes),
+ _humongous_chunks_size_in_bytes(humongous_chunks_size_in_bytes)
+ {}
+
+ size_t num_specialized_chunks() const {
+ return _num_specialized_chunks;
+ }
+
+ size_t num_small_chunks() const {
+ return _num_small_chunks;
+ }
+
+ size_t num_medium_chunks() const {
+ return _num_medium_chunks;
+ }
+
+ size_t num_humongous_chunks() const {
+ return _num_humongous_chunks;
+ }
+
+ size_t specialized_chunks_size_in_bytes() const {
+ return _specialized_chunks_size_in_bytes;
+ }
+
+ size_t small_chunks_size_in_bytes() const {
+ return _small_chunks_size_in_bytes;
+ }
+
+ size_t medium_chunks_size_in_bytes() const {
+ return _medium_chunks_size_in_bytes;
+ }
+
+ size_t humongous_chunks_size_in_bytes() const {
+ return _humongous_chunks_size_in_bytes;
+ }
+};
+
+#endif // SHARE_VM_MEMORY_METASPACE_CHUNK_FREE_LIST_SUMMARY_HPP
--- a/hotspot/src/share/vm/trace/trace.xml Tue Mar 18 08:00:21 2014 +0100
+++ b/hotspot/src/share/vm/trace/trace.xml Tue Mar 18 09:03:28 2014 +0100
@@ -221,6 +221,20 @@
<value type="METASPACEOBJTYPE" field="metaspaceObjectType" label="Metaspace Object Type" />
</event>
+ <event id="MetaspaceChunkFreeListSummary" path="vm/gc/metaspace/chunk_free_list_summary" label="Metaspace Chunk Free List Summary" is_instant="true">
+ <value type="UINT" field="gcId" label="GC ID" relation="GC_ID"/>
+ <value type="GCWHEN" field="when" label="When" />
+ <value type="METADATATYPE" field="metadataType" label="Metadata Type" />
+ <value type="ULONG" field="specializedChunks" label="Specialized Chunks" />
+ <value type="BYTES64" field="specializedChunksTotalSize" label="Specialized Chunks Total Size" />
+ <value type="ULONG" field="smallChunks" label="Small Chunks" />
+ <value type="BYTES64" field="smallChunksTotalSize" label="Small Chunks Total Size" />
+ <value type="ULONG" field="mediumChunks" label="Medium Chunks" />
+ <value type="BYTES64" field="mediumChunksTotalSize" label="Medium Chunks Total Size" />
+ <value type="ULONG" field="humongousChunks" label="Humongous Chunks" />
+ <value type="BYTES64" field="humongousChunksTotalSize" label="Humongous Chunks Total Size" />
+ </event>
+
<event id="PSHeapSummary" path="vm/gc/heap/ps_summary" label="Parallel Scavenge Heap Summary" is_instant="true">
<value type="UINT" field="gcId" label="GC ID" relation="GC_ID"/>
<value type="GCWHEN" field="when" label="When" />