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

Merge

......@@ -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) {
......
......@@ -669,8 +669,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;
......@@ -125,18 +126,49 @@ class PSHeapSummary : public GCHeapSummary {
};
class MetaspaceSummary : public StackObj {
size_t _capacity_until_GC;
MetaspaceSizes _meta_space;
MetaspaceSizes _data_space;
MetaspaceSizes _class_space;
MetaspaceChunkFreeListSummary _metaspace_chunk_free_list_summary;
MetaspaceChunkFreeListSummary _class_chunk_free_list_summary;
public:
MetaspaceSummary() : _meta_space(), _data_space(), _class_space() {}
MetaspaceSummary(const MetaspaceSizes& meta_space, const MetaspaceSizes& data_space, const MetaspaceSizes& class_space) :
_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()) {
......@@ -246,6 +270,7 @@ void GCTracer::send_meta_space_summary_event(GCWhen::Type when, const MetaspaceS
if (e.should_commit()) {
e.set_gcId(_shared_gc_info.id());
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_dataSpace(to_trace_struct(meta_space_summary.data_space()));
e.set_classSpace(to_trace_struct(meta_space_summary.class_space()));
......
......@@ -97,7 +97,13 @@ MetaspaceSummary CollectedHeap::create_metaspace_summary() {
MetaspaceAux::allocated_used_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() {
......@@ -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) {
......
......@@ -32,7 +32,9 @@
#include "memory/gcLocker.hpp"
#include "memory/metachunk.hpp"
#include "memory/metaspace.hpp"
#include "memory/metaspaceGCThresholdUpdater.hpp"
#include "memory/metaspaceShared.hpp"
#include "memory/metaspaceTracer.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
#include "runtime/atomic.inline.hpp"
......@@ -57,6 +59,7 @@ size_t const allocation_from_dictionary_limit = 4 * K;
MetaWord* last_allocated = 0;
size_t Metaspace::_compressed_class_space_size;
const MetaspaceTracer* Metaspace::_tracer = NULL;
// Used in declarations in SpaceManager and ChunkManager
enum ChunkIndex {
......@@ -182,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() {
......@@ -1436,19 +1481,21 @@ void MetaspaceGC::compute_new_size() {
expand_bytes = align_size_up(expand_bytes, Metaspace::commit_alignment());
// Don't expand unless it's significant
if (expand_bytes >= MinMetaspaceExpansion) {
MetaspaceGC::inc_capacity_until_GC(expand_bytes);
}
if (PrintGCDetails && Verbose) {
size_t new_capacity_until_GC = capacity_until_GC;
gclog_or_tty->print_cr(" expanding:"
" minimum_desired_capacity: %6.1fKB"
" expand_bytes: %6.1fKB"
" MinMetaspaceExpansion: %6.1fKB"
" new metaspace HWM: %6.1fKB",
minimum_desired_capacity / (double) K,
expand_bytes / (double) K,
MinMetaspaceExpansion / (double) K,
new_capacity_until_GC / (double) K);
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) {
gclog_or_tty->print_cr(" expanding:"
" minimum_desired_capacity: %6.1fKB"
" expand_bytes: %6.1fKB"
" MinMetaspaceExpansion: %6.1fKB"
" new metaspace HWM: %6.1fKB",
minimum_desired_capacity / (double) K,
expand_bytes / (double) K,
MinMetaspaceExpansion / (double) K,
new_capacity_until_GC / (double) K);
}
}
return;
}
......@@ -1527,7 +1574,10 @@ void MetaspaceGC::compute_new_size() {
// Don't shrink unless it's significant
if (shrink_bytes >= MinMetaspaceExpansion &&
((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() {
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) {
......@@ -3131,6 +3194,7 @@ void Metaspace::global_initialize() {
}
MetaspaceGC::initialize();
_tracer = new MetaspaceTracer();
}
Metachunk* Metaspace::get_initialization_chunk(MetadataType mdtype,
......@@ -3219,8 +3283,12 @@ MetaWord* Metaspace::expand_and_allocate(size_t word_size, MetadataType mdtype)
assert(delta_bytes > 0, "Must be");
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;
tracer()->report_gc_threshold(before_inc, after_inc,
MetaspaceGCThresholdUpdater::ExpandAndAllocate);
if (PrintGCDetails && Verbose) {
gclog_or_tty->print_cr("Increase capacity to GC from " SIZE_FORMAT
" to " SIZE_FORMAT, before_inc, after_inc);
......@@ -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);
if (result == NULL) {
tracer()->report_metaspace_allocation_failure(loader_data, word_size, type, mdtype);
// Allocation failed.
if (is_init_completed()) {
// Only start a GC if the bootstrapping has completed.
......@@ -3355,7 +3425,7 @@ MetaWord* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size,
}
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.
......@@ -3369,7 +3439,9 @@ size_t Metaspace::class_chunk_size(size_t 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 (Verbose && TraceMetadataChunkAllocation) {
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
}
}
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) {
assert(DumpSharedSpaces, "sanity");
......
......@@ -26,6 +26,7 @@
#include "memory/allocation.hpp"
#include "memory/memRegion.hpp"
#include "memory/metaspaceChunkFreeListSummary.hpp"
#include "runtime/virtualspace.hpp"
#include "utilities/exceptions.hpp"
......@@ -60,6 +61,7 @@ class ChunkManager;
class ClassLoaderData;
class Metablock;
class Metachunk;
class MetaspaceTracer;
class MetaWord;
class Mutex;
class outputStream;
......@@ -148,6 +150,8 @@ class Metaspace : public CHeapObj<mtClass> {
static ChunkManager* _chunk_manager_metadata;
static ChunkManager* _chunk_manager_class;
static const MetaspaceTracer* _tracer;
public:
static VirtualSpaceList* space_list() { return _space_list; }
static VirtualSpaceList* class_space_list() { return _class_space_list; }
......@@ -163,6 +167,8 @@ class Metaspace : public CHeapObj<mtClass> {
return mdtype == ClassType ? chunk_manager_class() : chunk_manager_metadata();
}
static const MetaspaceTracer* tracer() { return _tracer; }
private:
// This is used by DumpSharedSpaces only, where only _vsm is used. So we will
// maintain a single list for now.
......@@ -233,7 +239,9 @@ class Metaspace : public CHeapObj<mtClass> {
static void purge();
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;
// Debugging support
......@@ -347,6 +355,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
/*
* 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.
<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="GCWHEN" field="when" label="When" />
<value type="BYTES64" field="gcThreshold" label="GC Threshold" />
<structvalue type="MetaspaceSizes" field="metaspace" label="Total"/>
<structvalue type="MetaspaceSizes" field="dataSpace" label="Data"/>
<structvalue type="MetaspaceSizes" field="classSpace" label="Class"/>
</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">
<value type="UINT" field="gcId" label="GC ID" relation="GC_ID"/>
<value type="GCWHEN" field="when" label="When" />
......
......@@ -130,11 +130,26 @@ Now we can use the content + data type in declaring event fields.
<value type="UTF8" field="type" label="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"
type="U1" jvm_type="REFERENCETYPE">
<value type="UTF8" field="type" label="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"
type="U1" jvm_type="NARROWOOPMODE">
<value type="UTF8" field="mode" label="mode" />
......@@ -324,10 +339,22 @@ Now we can use the content + data type in declaring event fields.
<primary_type symbol="G1YCTYPE" datatype="U1" contenttype="G1YCTYPE"
type="u1" sizeop="sizeof(u1)" />
<!-- GCTHRESHOLDUPDATER -->
<primary_type symbol="GCTHRESHOLDUPDATER" datatype="U1" contenttype="GCTHRESHOLDUPDATER"
type="u1" sizeop="sizeof(u1)" />
<!-- REFERENCETYPE -->
<primary_type symbol="REFERENCETYPE" datatype="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 -->
<primary_type symbol="NARROWOOPMODE" datatype="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.
先完成此消息的编辑!
想要评论请 注册