提交 08838bd8 编写于 作者: E ehelin

8036703: Add trace event with statistics for the metaspace chunk free lists

Reviewed-by: stefank, mgerdin, coleenp, egahlin
上级 3b0968e1
......@@ -2496,7 +2496,8 @@ void CMSCollector::save_heap_summary() {
}
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) {
......
......@@ -665,8 +665,10 @@ void ParallelScavengeHeap::print_heap_change(size_t prev_used) {
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() {
......
......@@ -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 @@ class MetaspaceSummary : public StackObj {
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
......@@ -139,11 +139,21 @@ void GCTracer::report_object_count_after_gc(BoolObjectClosure* is_alive_cl) {
}
#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) {
......
......@@ -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 @@ typedef uint GCId;
class EvacuationInfo;
class GCHeapSummary;
class MetaspaceChunkFreeListSummary;
class MetaspaceSummary;
class PSHeapSummary;
class ReferenceProcessorStats;
......@@ -124,7 +126,8 @@ class GCTracer : public ResourceObj {
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 @@ class GCTracer : public ResourceObj {
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;
};
......
......@@ -64,6 +64,30 @@ void GCTracer::send_reference_stats_event(ReferenceType type, size_t count) cons
}
}
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()) {
......
......@@ -97,7 +97,13 @@ MetaspaceSummary CollectedHeap::create_metaspace_summary() {
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::unregister_nmethod(nmethod* nm) {
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) {
......
......@@ -185,6 +185,48 @@ class ChunkManager : public CHeapObj<mtInternal> {
// 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 @@ size_t MetaspaceAux::free_chunks_total_bytes() {
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) {
......
......@@ -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 @@ class MetaspaceAux : AllStatic {
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);
......
/*
* 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
......@@ -221,6 +221,20 @@ Declares a structure type that can be used in other events.
<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" />
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册