提交 63db5491 编写于 作者: E ehelin

Merge

...@@ -2496,7 +2496,8 @@ void CMSCollector::save_heap_summary() { ...@@ -2496,7 +2496,8 @@ void CMSCollector::save_heap_summary() {
} }
void CMSCollector::report_heap_summary(GCWhen::Type when) { 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) { void CMSCollector::collect_in_foreground(bool clear_all_soft_refs, GCCause::Cause cause) {
......
...@@ -669,8 +669,10 @@ void ParallelScavengeHeap::print_heap_change(size_t prev_used) { ...@@ -669,8 +669,10 @@ void ParallelScavengeHeap::print_heap_change(size_t prev_used) {
void ParallelScavengeHeap::trace_heap(GCWhen::Type when, GCTracer* gc_tracer) { void ParallelScavengeHeap::trace_heap(GCWhen::Type when, GCTracer* gc_tracer) {
const PSHeapSummary& heap_summary = create_ps_heap_summary(); const PSHeapSummary& heap_summary = create_ps_heap_summary();
gc_tracer->report_gc_heap_summary(when, heap_summary);
const MetaspaceSummary& metaspace_summary = create_metaspace_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() { ParallelScavengeHeap* ParallelScavengeHeap::heap() {
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#define SHARE_VM_GC_IMPLEMENTATION_SHARED_GCHEAPSUMMARY_HPP #define SHARE_VM_GC_IMPLEMENTATION_SHARED_GCHEAPSUMMARY_HPP
#include "memory/allocation.hpp" #include "memory/allocation.hpp"
#include "memory/metaspaceChunkFreeListSummary.hpp"
class VirtualSpaceSummary : public StackObj { class VirtualSpaceSummary : public StackObj {
HeapWord* _start; HeapWord* _start;
...@@ -125,18 +126,49 @@ class PSHeapSummary : public GCHeapSummary { ...@@ -125,18 +126,49 @@ class PSHeapSummary : public GCHeapSummary {
}; };
class MetaspaceSummary : public StackObj { class MetaspaceSummary : public StackObj {
size_t _capacity_until_GC;
MetaspaceSizes _meta_space; MetaspaceSizes _meta_space;
MetaspaceSizes _data_space; MetaspaceSizes _data_space;
MetaspaceSizes _class_space; MetaspaceSizes _class_space;
MetaspaceChunkFreeListSummary _metaspace_chunk_free_list_summary;
MetaspaceChunkFreeListSummary _class_chunk_free_list_summary;
public: public:
MetaspaceSummary() : _meta_space(), _data_space(), _class_space() {} MetaspaceSummary() :
MetaspaceSummary(const MetaspaceSizes& meta_space, const MetaspaceSizes& data_space, const MetaspaceSizes& class_space) : _capacity_until_GC(0),
_meta_space(meta_space), _data_space(data_space), _class_space(class_space) { } _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& meta_space() const { return _meta_space; }
const MetaspaceSizes& data_space() const { return _data_space; } const MetaspaceSizes& data_space() const { return _data_space; }
const MetaspaceSizes& class_space() const { return _class_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 #endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_GCHEAPSUMMARY_HPP
...@@ -139,11 +139,21 @@ void GCTracer::report_object_count_after_gc(BoolObjectClosure* is_alive_cl) { ...@@ -139,11 +139,21 @@ void GCTracer::report_object_count_after_gc(BoolObjectClosure* is_alive_cl) {
} }
#endif // INCLUDE_SERVICES #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(); assert_set_gc_id();
send_gc_heap_summary_event(when, heap_summary); 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) { void YoungGCTracer::report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions) {
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include "gc_implementation/shared/gcWhen.hpp" #include "gc_implementation/shared/gcWhen.hpp"
#include "gc_implementation/shared/copyFailedInfo.hpp" #include "gc_implementation/shared/copyFailedInfo.hpp"
#include "memory/allocation.hpp" #include "memory/allocation.hpp"
#include "memory/metaspace.hpp"
#include "memory/referenceType.hpp" #include "memory/referenceType.hpp"
#if INCLUDE_ALL_GCS #if INCLUDE_ALL_GCS
#include "gc_implementation/g1/g1YCTypes.hpp" #include "gc_implementation/g1/g1YCTypes.hpp"
...@@ -41,6 +42,7 @@ typedef uint GCId; ...@@ -41,6 +42,7 @@ typedef uint GCId;
class EvacuationInfo; class EvacuationInfo;
class GCHeapSummary; class GCHeapSummary;
class MetaspaceChunkFreeListSummary;
class MetaspaceSummary; class MetaspaceSummary;
class PSHeapSummary; class PSHeapSummary;
class ReferenceProcessorStats; class ReferenceProcessorStats;
...@@ -124,7 +126,8 @@ class GCTracer : public ResourceObj { ...@@ -124,7 +126,8 @@ class GCTracer : public ResourceObj {
public: public:
void report_gc_start(GCCause::Cause cause, const Ticks& timestamp); void report_gc_start(GCCause::Cause cause, const Ticks& timestamp);
void report_gc_end(const Ticks& timestamp, TimePartitions* time_partitions); 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_gc_reference_stats(const ReferenceProcessorStats& rp) const;
void report_object_count_after_gc(BoolObjectClosure* object_filter) NOT_SERVICES_RETURN; void report_object_count_after_gc(BoolObjectClosure* object_filter) NOT_SERVICES_RETURN;
bool has_reported_gc_start() const; bool has_reported_gc_start() const;
...@@ -138,6 +141,7 @@ class GCTracer : public ResourceObj { ...@@ -138,6 +141,7 @@ class GCTracer : public ResourceObj {
void send_garbage_collection_event() const; void send_garbage_collection_event() const;
void send_gc_heap_summary_event(GCWhen::Type when, const GCHeapSummary& heap_summary) 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_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_reference_stats_event(ReferenceType type, size_t count) const;
void send_phase_events(TimePartitions* time_partitions) 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 ...@@ -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 { void ParallelOldTracer::send_parallel_old_event() const {
EventGCParallelOld e(UNTIMED); EventGCParallelOld e(UNTIMED);
if (e.should_commit()) { if (e.should_commit()) {
...@@ -246,6 +270,7 @@ void GCTracer::send_meta_space_summary_event(GCWhen::Type when, const MetaspaceS ...@@ -246,6 +270,7 @@ void GCTracer::send_meta_space_summary_event(GCWhen::Type when, const MetaspaceS
if (e.should_commit()) { if (e.should_commit()) {
e.set_gcId(_shared_gc_info.id()); e.set_gcId(_shared_gc_info.id());
e.set_when((u1) when); e.set_when((u1) when);
e.set_gcThreshold(meta_space_summary.capacity_until_GC());
e.set_metaspace(to_trace_struct(meta_space_summary.meta_space())); e.set_metaspace(to_trace_struct(meta_space_summary.meta_space()));
e.set_dataSpace(to_trace_struct(meta_space_summary.data_space())); e.set_dataSpace(to_trace_struct(meta_space_summary.data_space()));
e.set_classSpace(to_trace_struct(meta_space_summary.class_space())); e.set_classSpace(to_trace_struct(meta_space_summary.class_space()));
......
...@@ -97,7 +97,13 @@ MetaspaceSummary CollectedHeap::create_metaspace_summary() { ...@@ -97,7 +97,13 @@ MetaspaceSummary CollectedHeap::create_metaspace_summary() {
MetaspaceAux::allocated_used_bytes(Metaspace::ClassType), MetaspaceAux::allocated_used_bytes(Metaspace::ClassType),
MetaspaceAux::reserved_bytes(Metaspace::ClassType)); MetaspaceAux::reserved_bytes(Metaspace::ClassType));
return MetaspaceSummary(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() { void CollectedHeap::print_heap_before_gc() {
...@@ -128,8 +134,10 @@ void CollectedHeap::unregister_nmethod(nmethod* nm) { ...@@ -128,8 +134,10 @@ void CollectedHeap::unregister_nmethod(nmethod* nm) {
void CollectedHeap::trace_heap(GCWhen::Type when, GCTracer* gc_tracer) { void CollectedHeap::trace_heap(GCWhen::Type when, GCTracer* gc_tracer) {
const GCHeapSummary& heap_summary = create_heap_summary(); const GCHeapSummary& heap_summary = create_heap_summary();
gc_tracer->report_gc_heap_summary(when, heap_summary);
const MetaspaceSummary& metaspace_summary = create_metaspace_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) { void CollectedHeap::trace_heap_before_gc(GCTracer* gc_tracer) {
......
...@@ -32,7 +32,9 @@ ...@@ -32,7 +32,9 @@
#include "memory/gcLocker.hpp" #include "memory/gcLocker.hpp"
#include "memory/metachunk.hpp" #include "memory/metachunk.hpp"
#include "memory/metaspace.hpp" #include "memory/metaspace.hpp"
#include "memory/metaspaceGCThresholdUpdater.hpp"
#include "memory/metaspaceShared.hpp" #include "memory/metaspaceShared.hpp"
#include "memory/metaspaceTracer.hpp"
#include "memory/resourceArea.hpp" #include "memory/resourceArea.hpp"
#include "memory/universe.hpp" #include "memory/universe.hpp"
#include "runtime/atomic.inline.hpp" #include "runtime/atomic.inline.hpp"
...@@ -57,6 +59,7 @@ size_t const allocation_from_dictionary_limit = 4 * K; ...@@ -57,6 +59,7 @@ size_t const allocation_from_dictionary_limit = 4 * K;
MetaWord* last_allocated = 0; MetaWord* last_allocated = 0;
size_t Metaspace::_compressed_class_space_size; size_t Metaspace::_compressed_class_space_size;
const MetaspaceTracer* Metaspace::_tracer = NULL;
// Used in declarations in SpaceManager and ChunkManager // Used in declarations in SpaceManager and ChunkManager
enum ChunkIndex { enum ChunkIndex {
...@@ -182,6 +185,48 @@ class ChunkManager : public CHeapObj<mtInternal> { ...@@ -182,6 +185,48 @@ class ChunkManager : public CHeapObj<mtInternal> {
// Remove from a list by size. Selects list based on size of chunk. // Remove from a list by size. Selects list based on size of chunk.
Metachunk* free_chunks_get(size_t chunk_word_size); 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 // Debug support
void verify(); void verify();
void slow_verify() { void slow_verify() {
...@@ -1436,10 +1481,11 @@ void MetaspaceGC::compute_new_size() { ...@@ -1436,10 +1481,11 @@ void MetaspaceGC::compute_new_size() {
expand_bytes = align_size_up(expand_bytes, Metaspace::commit_alignment()); expand_bytes = align_size_up(expand_bytes, Metaspace::commit_alignment());
// Don't expand unless it's significant // Don't expand unless it's significant
if (expand_bytes >= MinMetaspaceExpansion) { if (expand_bytes >= MinMetaspaceExpansion) {
MetaspaceGC::inc_capacity_until_GC(expand_bytes); size_t new_capacity_until_GC = MetaspaceGC::inc_capacity_until_GC(expand_bytes);
} Metaspace::tracer()->report_gc_threshold(capacity_until_GC,
new_capacity_until_GC,
MetaspaceGCThresholdUpdater::ComputeNewSize);
if (PrintGCDetails && Verbose) { if (PrintGCDetails && Verbose) {
size_t new_capacity_until_GC = capacity_until_GC;
gclog_or_tty->print_cr(" expanding:" gclog_or_tty->print_cr(" expanding:"
" minimum_desired_capacity: %6.1fKB" " minimum_desired_capacity: %6.1fKB"
" expand_bytes: %6.1fKB" " expand_bytes: %6.1fKB"
...@@ -1450,6 +1496,7 @@ void MetaspaceGC::compute_new_size() { ...@@ -1450,6 +1496,7 @@ void MetaspaceGC::compute_new_size() {
MinMetaspaceExpansion / (double) K, MinMetaspaceExpansion / (double) K,
new_capacity_until_GC / (double) K); new_capacity_until_GC / (double) K);
} }
}
return; return;
} }
...@@ -1527,7 +1574,10 @@ void MetaspaceGC::compute_new_size() { ...@@ -1527,7 +1574,10 @@ void MetaspaceGC::compute_new_size() {
// Don't shrink unless it's significant // Don't shrink unless it's significant
if (shrink_bytes >= MinMetaspaceExpansion && if (shrink_bytes >= MinMetaspaceExpansion &&
((capacity_until_GC - shrink_bytes) >= MetaspaceSize)) { ((capacity_until_GC - shrink_bytes) >= MetaspaceSize)) {
MetaspaceGC::dec_capacity_until_GC(shrink_bytes); size_t new_capacity_until_GC = MetaspaceGC::dec_capacity_until_GC(shrink_bytes);
Metaspace::tracer()->report_gc_threshold(capacity_until_GC,
new_capacity_until_GC,
MetaspaceGCThresholdUpdater::ComputeNewSize);
} }
} }
...@@ -2628,6 +2678,19 @@ size_t MetaspaceAux::free_chunks_total_bytes() { ...@@ -2628,6 +2678,19 @@ size_t MetaspaceAux::free_chunks_total_bytes() {
return free_chunks_total_words() * BytesPerWord; 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) { void MetaspaceAux::print_metaspace_change(size_t prev_metadata_used) {
gclog_or_tty->print(", [Metaspace:"); gclog_or_tty->print(", [Metaspace:");
if (PrintGCDetails && Verbose) { if (PrintGCDetails && Verbose) {
...@@ -3131,6 +3194,7 @@ void Metaspace::global_initialize() { ...@@ -3131,6 +3194,7 @@ void Metaspace::global_initialize() {
} }
MetaspaceGC::initialize(); MetaspaceGC::initialize();
_tracer = new MetaspaceTracer();
} }
Metachunk* Metaspace::get_initialization_chunk(MetadataType mdtype, Metachunk* Metaspace::get_initialization_chunk(MetadataType mdtype,
...@@ -3219,8 +3283,12 @@ MetaWord* Metaspace::expand_and_allocate(size_t word_size, MetadataType mdtype) ...@@ -3219,8 +3283,12 @@ MetaWord* Metaspace::expand_and_allocate(size_t word_size, MetadataType mdtype)
assert(delta_bytes > 0, "Must be"); assert(delta_bytes > 0, "Must be");
size_t after_inc = MetaspaceGC::inc_capacity_until_GC(delta_bytes); size_t after_inc = MetaspaceGC::inc_capacity_until_GC(delta_bytes);
// capacity_until_GC might be updated concurrently, must calculate previous value.
size_t before_inc = after_inc - delta_bytes; size_t before_inc = after_inc - delta_bytes;
tracer()->report_gc_threshold(before_inc, after_inc,
MetaspaceGCThresholdUpdater::ExpandAndAllocate);
if (PrintGCDetails && Verbose) { if (PrintGCDetails && Verbose) {
gclog_or_tty->print_cr("Increase capacity to GC from " SIZE_FORMAT gclog_or_tty->print_cr("Increase capacity to GC from " SIZE_FORMAT
" to " SIZE_FORMAT, before_inc, after_inc); " to " SIZE_FORMAT, before_inc, after_inc);
...@@ -3344,6 +3412,8 @@ MetaWord* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size, ...@@ -3344,6 +3412,8 @@ MetaWord* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size,
MetaWord* result = loader_data->metaspace_non_null()->allocate(word_size, mdtype); MetaWord* result = loader_data->metaspace_non_null()->allocate(word_size, mdtype);
if (result == NULL) { if (result == NULL) {
tracer()->report_metaspace_allocation_failure(loader_data, word_size, type, mdtype);
// Allocation failed. // Allocation failed.
if (is_init_completed()) { if (is_init_completed()) {
// Only start a GC if the bootstrapping has completed. // Only start a GC if the bootstrapping has completed.
...@@ -3355,7 +3425,7 @@ MetaWord* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size, ...@@ -3355,7 +3425,7 @@ MetaWord* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size,
} }
if (result == NULL) { if (result == NULL) {
report_metadata_oome(loader_data, word_size, mdtype, CHECK_NULL); report_metadata_oome(loader_data, word_size, type, mdtype, CHECK_NULL);
} }
// Zero initialize. // Zero initialize.
...@@ -3369,7 +3439,9 @@ size_t Metaspace::class_chunk_size(size_t word_size) { ...@@ -3369,7 +3439,9 @@ size_t Metaspace::class_chunk_size(size_t word_size) {
return class_vsm()->calc_chunk_size(word_size); return class_vsm()->calc_chunk_size(word_size);
} }
void Metaspace::report_metadata_oome(ClassLoaderData* loader_data, size_t word_size, MetadataType mdtype, TRAPS) { void Metaspace::report_metadata_oome(ClassLoaderData* loader_data, size_t word_size, MetaspaceObj::Type type, MetadataType mdtype, TRAPS) {
tracer()->report_metadata_oom(loader_data, word_size, type, mdtype);
// If result is still null, we are out of memory. // If result is still null, we are out of memory.
if (Verbose && TraceMetadataChunkAllocation) { if (Verbose && TraceMetadataChunkAllocation) {
gclog_or_tty->print_cr("Metaspace allocation failed for size " gclog_or_tty->print_cr("Metaspace allocation failed for size "
...@@ -3412,6 +3484,16 @@ void Metaspace::report_metadata_oome(ClassLoaderData* loader_data, size_t word_s ...@@ -3412,6 +3484,16 @@ void Metaspace::report_metadata_oome(ClassLoaderData* loader_data, size_t word_s
} }
} }
const char* Metaspace::metadata_type_name(Metaspace::MetadataType mdtype) {
switch (mdtype) {
case Metaspace::ClassType: return "Class";
case Metaspace::NonClassType: return "Metadata";
default:
assert(false, err_msg("Got bad mdtype: %d", (int) mdtype));
return NULL;
}
}
void Metaspace::record_allocation(void* ptr, MetaspaceObj::Type type, size_t word_size) { void Metaspace::record_allocation(void* ptr, MetaspaceObj::Type type, size_t word_size) {
assert(DumpSharedSpaces, "sanity"); assert(DumpSharedSpaces, "sanity");
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "memory/allocation.hpp" #include "memory/allocation.hpp"
#include "memory/memRegion.hpp" #include "memory/memRegion.hpp"
#include "memory/metaspaceChunkFreeListSummary.hpp"
#include "runtime/virtualspace.hpp" #include "runtime/virtualspace.hpp"
#include "utilities/exceptions.hpp" #include "utilities/exceptions.hpp"
...@@ -60,6 +61,7 @@ class ChunkManager; ...@@ -60,6 +61,7 @@ class ChunkManager;
class ClassLoaderData; class ClassLoaderData;
class Metablock; class Metablock;
class Metachunk; class Metachunk;
class MetaspaceTracer;
class MetaWord; class MetaWord;
class Mutex; class Mutex;
class outputStream; class outputStream;
...@@ -148,6 +150,8 @@ class Metaspace : public CHeapObj<mtClass> { ...@@ -148,6 +150,8 @@ class Metaspace : public CHeapObj<mtClass> {
static ChunkManager* _chunk_manager_metadata; static ChunkManager* _chunk_manager_metadata;
static ChunkManager* _chunk_manager_class; static ChunkManager* _chunk_manager_class;
static const MetaspaceTracer* _tracer;
public: public:
static VirtualSpaceList* space_list() { return _space_list; } static VirtualSpaceList* space_list() { return _space_list; }
static VirtualSpaceList* class_space_list() { return _class_space_list; } static VirtualSpaceList* class_space_list() { return _class_space_list; }
...@@ -163,6 +167,8 @@ class Metaspace : public CHeapObj<mtClass> { ...@@ -163,6 +167,8 @@ class Metaspace : public CHeapObj<mtClass> {
return mdtype == ClassType ? chunk_manager_class() : chunk_manager_metadata(); return mdtype == ClassType ? chunk_manager_class() : chunk_manager_metadata();
} }
static const MetaspaceTracer* tracer() { return _tracer; }
private: private:
// This is used by DumpSharedSpaces only, where only _vsm is used. So we will // This is used by DumpSharedSpaces only, where only _vsm is used. So we will
// maintain a single list for now. // maintain a single list for now.
...@@ -233,7 +239,9 @@ class Metaspace : public CHeapObj<mtClass> { ...@@ -233,7 +239,9 @@ class Metaspace : public CHeapObj<mtClass> {
static void purge(); static void purge();
static void report_metadata_oome(ClassLoaderData* loader_data, size_t word_size, static void report_metadata_oome(ClassLoaderData* loader_data, size_t word_size,
MetadataType mdtype, TRAPS); MetaspaceObj::Type type, MetadataType mdtype, TRAPS);
static const char* metadata_type_name(Metaspace::MetadataType mdtype);
void print_on(outputStream* st) const; void print_on(outputStream* st) const;
// Debugging support // Debugging support
...@@ -347,6 +355,9 @@ class MetaspaceAux : AllStatic { ...@@ -347,6 +355,9 @@ class MetaspaceAux : AllStatic {
return min_chunk_size_words() * BytesPerWord; 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. // Print change in used metadata.
static void print_metaspace_change(size_t prev_metadata_used); static void print_metaspace_change(size_t prev_metadata_used);
static void print_on(outputStream * out); 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
/*
* 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_GC_THRESHOLD_UPDATER_HPP
#define SHARE_VM_MEMORY_METASPACE_GC_THRESHOLD_UPDATER_HPP
#include "memory/allocation.hpp"
#include "utilities/debug.hpp"
class MetaspaceGCThresholdUpdater : public AllStatic {
public:
enum Type {
ComputeNewSize,
ExpandAndAllocate,
Last
};
static const char* to_string(MetaspaceGCThresholdUpdater::Type updater) {
switch (updater) {
case ComputeNewSize:
return "compute_new_size";
case ExpandAndAllocate:
return "expand_and_allocate";
default:
assert(false, err_msg("Got bad updater: %d", (int) updater));
return NULL;
};
}
};
#endif // SHARE_VM_MEMORY_METASPACE_GC_THRESHOLD_UPDATER_HPP
/*
* 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.
*
*/
#include "precompiled.hpp"
#include "classfile/classLoaderData.hpp"
#include "memory/metaspaceTracer.hpp"
#include "trace/tracing.hpp"
#include "trace/traceBackend.hpp"
void MetaspaceTracer::report_gc_threshold(size_t old_val,
size_t new_val,
MetaspaceGCThresholdUpdater::Type updater) const {
EventMetaspaceGCThreshold event;
if (event.should_commit()) {
event.set_oldValue(old_val);
event.set_newValue(new_val);
event.set_updater((u1)updater);
event.commit();
}
}
void MetaspaceTracer::report_metaspace_allocation_failure(ClassLoaderData *cld,
size_t word_size,
MetaspaceObj::Type objtype,
Metaspace::MetadataType mdtype) const {
send_allocation_failure_event<EventMetaspaceAllocationFailure>(cld, word_size, objtype, mdtype);
}
void MetaspaceTracer::report_metadata_oom(ClassLoaderData *cld,
size_t word_size,
MetaspaceObj::Type objtype,
Metaspace::MetadataType mdtype) const {
send_allocation_failure_event<EventMetaspaceOOM>(cld, word_size, objtype, mdtype);
}
template <typename E>
void MetaspaceTracer::send_allocation_failure_event(ClassLoaderData *cld,
size_t word_size,
MetaspaceObj::Type objtype,
Metaspace::MetadataType mdtype) const {
E event;
if (event.should_commit()) {
if (cld->is_anonymous()) {
event.set_classLoader(NULL);
event.set_anonymousClassLoader(true);
} else {
if (cld->is_the_null_class_loader_data()) {
event.set_classLoader((Klass*) NULL);
} else {
event.set_classLoader(cld->class_loader()->klass());
}
event.set_anonymousClassLoader(false);
}
event.set_size(word_size * BytesPerWord);
event.set_metadataType((u1) mdtype);
event.set_metaspaceObjectType((u1) objtype);
event.commit();
}
}
/*
* 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_TRACER_HPP
#define SHARE_VM_MEMORY_METASPACE_TRACER_HPP
#include "memory/allocation.hpp"
#include "memory/metaspace.hpp"
#include "memory/metaspaceGCThresholdUpdater.hpp"
class ClassLoaderData;
class MetaspaceTracer : public CHeapObj<mtTracing> {
template <typename E>
void send_allocation_failure_event(ClassLoaderData *cld,
size_t word_size,
MetaspaceObj::Type objtype,
Metaspace::MetadataType mdtype) const;
public:
void report_gc_threshold(size_t old_val,
size_t new_val,
MetaspaceGCThresholdUpdater::Type updater) const;
void report_metaspace_allocation_failure(ClassLoaderData *cld,
size_t word_size,
MetaspaceObj::Type objtype,
Metaspace::MetadataType mdtype) const;
void report_metadata_oom(ClassLoaderData *cld,
size_t word_size,
MetaspaceObj::Type objtype,
Metaspace::MetadataType mdtype) const;
};
#endif // SHARE_VM_MEMORY_METASPACE_TRACER_HPP
...@@ -193,11 +193,48 @@ Declares a structure type that can be used in other events. ...@@ -193,11 +193,48 @@ Declares a structure type that can be used in other events.
<event id="MetaspaceSummary" path="vm/gc/heap/metaspace_summary" label="Metaspace Summary" is_instant="true"> <event id="MetaspaceSummary" path="vm/gc/heap/metaspace_summary" label="Metaspace Summary" is_instant="true">
<value type="UINT" field="gcId" label="GC ID" relation="GC_ID"/> <value type="UINT" field="gcId" label="GC ID" relation="GC_ID"/>
<value type="GCWHEN" field="when" label="When" /> <value type="GCWHEN" field="when" label="When" />
<value type="BYTES64" field="gcThreshold" label="GC Threshold" />
<structvalue type="MetaspaceSizes" field="metaspace" label="Total"/> <structvalue type="MetaspaceSizes" field="metaspace" label="Total"/>
<structvalue type="MetaspaceSizes" field="dataSpace" label="Data"/> <structvalue type="MetaspaceSizes" field="dataSpace" label="Data"/>
<structvalue type="MetaspaceSizes" field="classSpace" label="Class"/> <structvalue type="MetaspaceSizes" field="classSpace" label="Class"/>
</event> </event>
<event id="MetaspaceGCThreshold" path="vm/gc/metaspace/gc_threshold" label="Metaspace GC Threshold" is_instant="true">
<value type="BYTES64" field="oldValue" label="Old Value" />
<value type="BYTES64" field="newValue" label="New Value" />
<value type="GCTHRESHOLDUPDATER" field="updater" label="Updater" />
</event>
<event id="MetaspaceAllocationFailure" path="vm/gc/metaspace/allocation_failure" label="Metaspace Allocation Failure" is_instant="true" has_stacktrace="true">
<value type="CLASS" field="classLoader" label="Class Loader" />
<value type="BOOLEAN" field="anonymousClassLoader" label="Anonymous Class Loader" />
<value type="BYTES64" field="size" label="Size" />
<value type="METADATATYPE" field="metadataType" label="Metadata Type" />
<value type="METASPACEOBJTYPE" field="metaspaceObjectType" label="Metaspace Object Type" />
</event>
<event id="MetaspaceOOM" path="vm/gc/metaspace/out_of_memory" label="Metaspace Out of Memory" is_instant="true" has_stacktrace="true">
<value type="CLASS" field="classLoader" label="Class Loader" />
<value type="BOOLEAN" field="anonymousClassLoader" label="Anonymous Class Loader" />
<value type="BYTES64" field="size" label="Size" />
<value type="METADATATYPE" field="metadataType" label="Metadata Type" />
<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"> <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="UINT" field="gcId" label="GC ID" relation="GC_ID"/>
<value type="GCWHEN" field="when" label="When" /> <value type="GCWHEN" field="when" label="When" />
......
...@@ -130,11 +130,26 @@ Now we can use the content + data type in declaring event fields. ...@@ -130,11 +130,26 @@ Now we can use the content + data type in declaring event fields.
<value type="UTF8" field="type" label="type" /> <value type="UTF8" field="type" label="type" />
</content_type> </content_type>
<content_type id="GCThresholdUpdater" hr_name="GC Treshold Updater"
type="U1" jvm_type="GCTHRESHOLDUPDATER">
<value type="UTF8" field="updater" label="updater" />
</content_type>
<content_type id="ReferenceType" hr_name="Reference Type" <content_type id="ReferenceType" hr_name="Reference Type"
type="U1" jvm_type="REFERENCETYPE"> type="U1" jvm_type="REFERENCETYPE">
<value type="UTF8" field="type" label="type" /> <value type="UTF8" field="type" label="type" />
</content_type> </content_type>
<content_type id="MetadataType" hr_name="Metadata Type"
type="U1" jvm_type="METADATATYPE">
<value type="UTF8" field="type" label="type" />
</content_type>
<content_type id="MetaspaceObjectType" hr_name="Metaspace Object Type"
type="U1" jvm_type="METASPACEOBJTYPE">
<value type="UTF8" field="type" label="type" />
</content_type>
<content_type id="NARROW_OOP_MODE" hr_name="Narrow Oop Mode" <content_type id="NARROW_OOP_MODE" hr_name="Narrow Oop Mode"
type="U1" jvm_type="NARROWOOPMODE"> type="U1" jvm_type="NARROWOOPMODE">
<value type="UTF8" field="mode" label="mode" /> <value type="UTF8" field="mode" label="mode" />
...@@ -324,10 +339,22 @@ Now we can use the content + data type in declaring event fields. ...@@ -324,10 +339,22 @@ Now we can use the content + data type in declaring event fields.
<primary_type symbol="G1YCTYPE" datatype="U1" contenttype="G1YCTYPE" <primary_type symbol="G1YCTYPE" datatype="U1" contenttype="G1YCTYPE"
type="u1" sizeop="sizeof(u1)" /> type="u1" sizeop="sizeof(u1)" />
<!-- GCTHRESHOLDUPDATER -->
<primary_type symbol="GCTHRESHOLDUPDATER" datatype="U1" contenttype="GCTHRESHOLDUPDATER"
type="u1" sizeop="sizeof(u1)" />
<!-- REFERENCETYPE --> <!-- REFERENCETYPE -->
<primary_type symbol="REFERENCETYPE" datatype="U1" <primary_type symbol="REFERENCETYPE" datatype="U1"
contenttype="REFERENCETYPE" type="u1" sizeop="sizeof(u1)" /> contenttype="REFERENCETYPE" type="u1" sizeop="sizeof(u1)" />
<!-- METADATATYPE -->
<primary_type symbol="METADATATYPE" datatype="U1"
contenttype="METADATATYPE" type="u1" sizeop="sizeof(u1)" />
<!-- METADATAOBJTYPE -->
<primary_type symbol="METASPACEOBJTYPE" datatype="U1"
contenttype="METASPACEOBJTYPE" type="u1" sizeop="sizeof(u1)" />
<!-- NARROWOOPMODE --> <!-- NARROWOOPMODE -->
<primary_type symbol="NARROWOOPMODE" datatype="U1" <primary_type symbol="NARROWOOPMODE" datatype="U1"
contenttype="NARROWOOPMODE" type="u1" sizeop="sizeof(u1)" /> contenttype="NARROWOOPMODE" type="u1" sizeop="sizeof(u1)" />
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册