mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-21 13:23:17 +00:00
8251392: Consolidate Metaspace Statistics
Reviewed-by: coleenp, zgu
This commit is contained in:
parent
3e97b07a68
commit
554caf33a0
@ -331,9 +331,10 @@ void EpsilonHeap::print_heap_info(size_t used) const {
|
||||
}
|
||||
|
||||
void EpsilonHeap::print_metaspace_info() const {
|
||||
size_t reserved = MetaspaceUtils::reserved_bytes();
|
||||
size_t committed = MetaspaceUtils::committed_bytes();
|
||||
size_t used = MetaspaceUtils::used_bytes();
|
||||
MetaspaceCombinedStats stats = MetaspaceUtils::get_combined_statistics();
|
||||
size_t reserved = stats.reserved();
|
||||
size_t committed = stats.committed();
|
||||
size_t used = stats.used();
|
||||
|
||||
if (reserved != 0) {
|
||||
log_info(gc, metaspace)("Metaspace: " SIZE_FORMAT "%s reserved, " SIZE_FORMAT "%s (%.2f%%) committed, "
|
||||
|
||||
@ -111,7 +111,6 @@ void EpsilonMonitoringSupport::update_counters() {
|
||||
_heap_counters->update_all();
|
||||
_space_counters->update_all(capacity, used);
|
||||
MetaspaceCounters::update_performance_counters();
|
||||
CompressedClassSpaceCounters::update_performance_counters();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -35,6 +35,7 @@ G1HeapTransition::Data::Data(G1CollectedHeap* g1_heap) :
|
||||
_old_length(g1_heap->old_regions_count()),
|
||||
_archive_length(g1_heap->archive_regions_count()),
|
||||
_humongous_length(g1_heap->humongous_regions_count()),
|
||||
_meta_sizes(MetaspaceUtils::get_combined_statistics()),
|
||||
_eden_length_per_node(NULL),
|
||||
_survivor_length_per_node(NULL) {
|
||||
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
#define SHARE_GC_G1_G1HEAPTRANSITION_HPP
|
||||
|
||||
#include "gc/shared/plab.hpp"
|
||||
#include "memory/metaspace/metaspaceSizesSnapshot.hpp"
|
||||
#include "memory/metaspaceStats.hpp"
|
||||
|
||||
class G1CollectedHeap;
|
||||
|
||||
@ -37,7 +37,7 @@ class G1HeapTransition {
|
||||
size_t _old_length;
|
||||
size_t _archive_length;
|
||||
size_t _humongous_length;
|
||||
const metaspace::MetaspaceSizesSnapshot _meta_sizes;
|
||||
const MetaspaceCombinedStats _meta_sizes;
|
||||
|
||||
// Only includes current eden regions.
|
||||
uint* _eden_length_per_node;
|
||||
|
||||
@ -303,7 +303,6 @@ void G1MonitoringSupport::update_sizes() {
|
||||
_old_gen_counters->update_all();
|
||||
|
||||
MetaspaceCounters::update_performance_counters();
|
||||
CompressedClassSpaceCounters::update_performance_counters();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -184,7 +184,6 @@ void ParallelScavengeHeap::update_counters() {
|
||||
young_gen()->update_counters();
|
||||
old_gen()->update_counters();
|
||||
MetaspaceCounters::update_performance_counters();
|
||||
CompressedClassSpaceCounters::update_performance_counters();
|
||||
}
|
||||
|
||||
size_t ParallelScavengeHeap::capacity() const {
|
||||
|
||||
@ -128,25 +128,12 @@ GCHeapSummary CollectedHeap::create_heap_summary() {
|
||||
}
|
||||
|
||||
MetaspaceSummary CollectedHeap::create_metaspace_summary() {
|
||||
const MetaspaceSizes meta_space(
|
||||
MetaspaceUtils::committed_bytes(),
|
||||
MetaspaceUtils::used_bytes(),
|
||||
MetaspaceUtils::reserved_bytes());
|
||||
const MetaspaceSizes data_space(
|
||||
MetaspaceUtils::committed_bytes(Metaspace::NonClassType),
|
||||
MetaspaceUtils::used_bytes(Metaspace::NonClassType),
|
||||
MetaspaceUtils::reserved_bytes(Metaspace::NonClassType));
|
||||
const MetaspaceSizes class_space(
|
||||
MetaspaceUtils::committed_bytes(Metaspace::ClassType),
|
||||
MetaspaceUtils::used_bytes(Metaspace::ClassType),
|
||||
MetaspaceUtils::reserved_bytes(Metaspace::ClassType));
|
||||
|
||||
const MetaspaceChunkFreeListSummary& ms_chunk_free_list_summary =
|
||||
MetaspaceUtils::chunk_free_list_summary(Metaspace::NonClassType);
|
||||
const MetaspaceChunkFreeListSummary& class_chunk_free_list_summary =
|
||||
MetaspaceUtils::chunk_free_list_summary(Metaspace::ClassType);
|
||||
|
||||
return MetaspaceSummary(MetaspaceGC::capacity_until_GC(), meta_space, data_space, class_space,
|
||||
return MetaspaceSummary(MetaspaceGC::capacity_until_GC(),
|
||||
MetaspaceUtils::get_combined_statistics(),
|
||||
ms_chunk_free_list_summary, class_chunk_free_list_summary);
|
||||
}
|
||||
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
#define SHARE_GC_SHARED_GCHEAPSUMMARY_HPP
|
||||
|
||||
#include "memory/allocation.hpp"
|
||||
#include "memory/metaspaceStats.hpp"
|
||||
#include "memory/metaspaceChunkFreeListSummary.hpp"
|
||||
|
||||
class VirtualSpaceSummary : public StackObj {
|
||||
@ -61,21 +62,6 @@ public:
|
||||
size_t size() const { return (uintptr_t)_end - (uintptr_t)_start; }
|
||||
};
|
||||
|
||||
class MetaspaceSizes : public StackObj {
|
||||
size_t _committed;
|
||||
size_t _used;
|
||||
size_t _reserved;
|
||||
|
||||
public:
|
||||
MetaspaceSizes() : _committed(0), _used(0), _reserved(0) {}
|
||||
MetaspaceSizes(size_t committed, size_t used, size_t reserved) :
|
||||
_committed(committed), _used(used), _reserved(reserved) {}
|
||||
|
||||
size_t committed() const { return _committed; }
|
||||
size_t used() const { return _used; }
|
||||
size_t reserved() const { return _reserved; }
|
||||
};
|
||||
|
||||
class GCHeapSummary;
|
||||
class PSHeapSummary;
|
||||
class G1HeapSummary;
|
||||
@ -147,39 +133,29 @@ class G1HeapSummary : public GCHeapSummary {
|
||||
|
||||
class MetaspaceSummary : public StackObj {
|
||||
size_t _capacity_until_GC;
|
||||
MetaspaceSizes _meta_space;
|
||||
MetaspaceSizes _data_space;
|
||||
MetaspaceSizes _class_space;
|
||||
MetaspaceCombinedStats _stats;
|
||||
MetaspaceChunkFreeListSummary _metaspace_chunk_free_list_summary;
|
||||
MetaspaceChunkFreeListSummary _class_chunk_free_list_summary;
|
||||
|
||||
public:
|
||||
MetaspaceSummary() :
|
||||
_capacity_until_GC(0),
|
||||
_meta_space(),
|
||||
_data_space(),
|
||||
_class_space(),
|
||||
_stats(),
|
||||
_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 MetaspaceCombinedStats& stats,
|
||||
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),
|
||||
_stats(stats),
|
||||
_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 MetaspaceCombinedStats& stats() const { return _stats; }
|
||||
|
||||
const MetaspaceChunkFreeListSummary& metaspace_chunk_free_list_summary() const {
|
||||
return _metaspace_chunk_free_list_summary;
|
||||
|
||||
@ -265,13 +265,11 @@ void GCTracer::send_gc_heap_summary_event(GCWhen::Type when, const GCHeapSummary
|
||||
heap_summary.accept(&visitor);
|
||||
}
|
||||
|
||||
static JfrStructMetaspaceSizes to_struct(const MetaspaceSizes& sizes) {
|
||||
static JfrStructMetaspaceSizes to_struct(const MetaspaceStats& sizes) {
|
||||
JfrStructMetaspaceSizes meta_sizes;
|
||||
|
||||
meta_sizes.set_committed(sizes.committed());
|
||||
meta_sizes.set_used(sizes.used());
|
||||
meta_sizes.set_reserved(sizes.reserved());
|
||||
|
||||
return meta_sizes;
|
||||
}
|
||||
|
||||
@ -281,9 +279,9 @@ void GCTracer::send_meta_space_summary_event(GCWhen::Type when, const MetaspaceS
|
||||
e.set_gcId(GCId::current());
|
||||
e.set_when((u1) when);
|
||||
e.set_gcThreshold(meta_space_summary.capacity_until_GC());
|
||||
e.set_metaspace(to_struct(meta_space_summary.meta_space()));
|
||||
e.set_dataSpace(to_struct(meta_space_summary.data_space()));
|
||||
e.set_classSpace(to_struct(meta_space_summary.class_space()));
|
||||
e.set_metaspace(to_struct(meta_space_summary.stats())); // total stats (class + nonclass)
|
||||
e.set_dataSpace(to_struct(meta_space_summary.stats().non_class_space_stats())); // "dataspace" aka non-class space
|
||||
e.set_classSpace(to_struct(meta_space_summary.stats().class_space_stats()));
|
||||
e.commit();
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,7 +57,6 @@
|
||||
#include "gc/shared/weakProcessor.hpp"
|
||||
#include "gc/shared/workgroup.hpp"
|
||||
#include "memory/iterator.hpp"
|
||||
#include "memory/metaspace/metaspaceSizesSnapshot.hpp"
|
||||
#include "memory/metaspaceCounters.hpp"
|
||||
#include "memory/metaspaceUtils.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
@ -1228,7 +1227,6 @@ void GenCollectedHeap::gc_epilogue(bool full) {
|
||||
generation_iterate(&blk, false); // not old-to-young.
|
||||
|
||||
MetaspaceCounters::update_performance_counters();
|
||||
CompressedClassSpaceCounters::update_performance_counters();
|
||||
};
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
||||
@ -26,7 +26,8 @@
|
||||
#ifndef SHARE_GC_SHARED_PREGCVALUES_HPP
|
||||
#define SHARE_GC_SHARED_PREGCVALUES_HPP
|
||||
|
||||
#include "memory/metaspace/metaspaceSizesSnapshot.hpp"
|
||||
#include "memory/metaspaceStats.hpp"
|
||||
#include "memory/metaspaceUtils.hpp"
|
||||
|
||||
// Simple class for storing info about the heap at the start of GC, to be used
|
||||
// after GC for comparison/printing.
|
||||
@ -47,7 +48,8 @@ public:
|
||||
_from_used(from_used),
|
||||
_from_capacity(from_capacity),
|
||||
_old_gen_used(old_gen_used),
|
||||
_old_gen_capacity(old_gen_capacity) { }
|
||||
_old_gen_capacity(old_gen_capacity),
|
||||
_meta_sizes(MetaspaceUtils::get_combined_statistics()){ }
|
||||
|
||||
size_t young_gen_used() const { return _young_gen_used; }
|
||||
size_t young_gen_capacity() const { return _young_gen_capacity; }
|
||||
@ -57,7 +59,7 @@ public:
|
||||
size_t from_capacity() const { return _from_capacity; }
|
||||
size_t old_gen_used() const { return _old_gen_used; }
|
||||
size_t old_gen_capacity() const { return _old_gen_capacity; }
|
||||
const metaspace::MetaspaceSizesSnapshot& metaspace_sizes() const { return _meta_sizes; }
|
||||
const MetaspaceCombinedStats& metaspace_sizes() const { return _meta_sizes; }
|
||||
|
||||
private:
|
||||
const size_t _young_gen_used;
|
||||
@ -68,7 +70,7 @@ private:
|
||||
const size_t _from_capacity;
|
||||
const size_t _old_gen_used;
|
||||
const size_t _old_gen_capacity;
|
||||
const metaspace::MetaspaceSizesSnapshot _meta_sizes;
|
||||
const MetaspaceCombinedStats _meta_sizes;
|
||||
};
|
||||
|
||||
#endif // SHARE_GC_SHARED_PREGCVALUES_HPP
|
||||
|
||||
@ -41,6 +41,7 @@
|
||||
#include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp"
|
||||
#include "memory/iterator.hpp"
|
||||
#include "memory/metaspaceUtils.hpp"
|
||||
#include "memory/metaspaceStats.hpp"
|
||||
#include "memory/universe.hpp"
|
||||
#include "runtime/atomic.hpp"
|
||||
|
||||
@ -187,8 +188,7 @@ void ShenandoahControlThread::run_service() {
|
||||
|
||||
heap->reset_bytes_allocated_since_gc_start();
|
||||
|
||||
// Use default constructor to snapshot the Metaspace state before GC.
|
||||
metaspace::MetaspaceSizesSnapshot meta_sizes;
|
||||
MetaspaceCombinedStats meta_sizes = MetaspaceUtils::get_combined_statistics();
|
||||
|
||||
// If GC was requested, we are sampling the counters even without actual triggers
|
||||
// from allocation machinery. This captures GC phases more accurately.
|
||||
|
||||
@ -101,6 +101,5 @@ void ShenandoahMonitoringSupport::update_counters() {
|
||||
_heap_region_counters->update();
|
||||
|
||||
MetaspaceCounters::update_performance_counters();
|
||||
CompressedClassSpaceCounters::update_performance_counters();
|
||||
}
|
||||
}
|
||||
|
||||
@ -89,7 +89,6 @@ void ZServiceabilityCounters::update_sizes() {
|
||||
_space_counters.update_used(used);
|
||||
|
||||
MetaspaceCounters::update_performance_counters();
|
||||
CompressedClassSpaceCounters::update_performance_counters();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1211,12 +1211,13 @@ void ZStatNMethods::print() {
|
||||
// Stat metaspace
|
||||
//
|
||||
void ZStatMetaspace::print() {
|
||||
MetaspaceCombinedStats stats = MetaspaceUtils::get_combined_statistics();
|
||||
log_info(gc, metaspace)("Metaspace: "
|
||||
SIZE_FORMAT "M used, "
|
||||
SIZE_FORMAT "M committed, " SIZE_FORMAT "M reserved",
|
||||
MetaspaceUtils::used_bytes() / M,
|
||||
MetaspaceUtils::committed_bytes() / M,
|
||||
MetaspaceUtils::reserved_bytes() / M);
|
||||
stats.used() / M,
|
||||
stats.committed() / M,
|
||||
stats.reserved() / M);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2017, 2021 SAP SE. 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
|
||||
@ -33,14 +34,15 @@
|
||||
#include "memory/metaspace/chunkHeaderPool.hpp"
|
||||
#include "memory/metaspace/chunkManager.hpp"
|
||||
#include "memory/metaspace/commitLimiter.hpp"
|
||||
#include "memory/metaspace/internalStats.hpp"
|
||||
#include "memory/metaspace/metaspaceCommon.hpp"
|
||||
#include "memory/metaspace/metaspaceContext.hpp"
|
||||
#include "memory/metaspace/metaspaceReporter.hpp"
|
||||
#include "memory/metaspace/metaspaceSettings.hpp"
|
||||
#include "memory/metaspace/metaspaceSizesSnapshot.hpp"
|
||||
#include "memory/metaspace/runningCounters.hpp"
|
||||
#include "memory/metaspace/virtualSpaceList.hpp"
|
||||
#include "memory/metaspaceTracer.hpp"
|
||||
#include "memory/metaspaceStats.hpp"
|
||||
#include "memory/metaspaceUtils.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "memory/universe.hpp"
|
||||
@ -87,8 +89,65 @@ size_t MetaspaceUtils::committed_words(Metaspace::MetadataType mdtype) {
|
||||
return mdtype == Metaspace::ClassType ? RunningCounters::committed_words_class() : RunningCounters::committed_words_nonclass();
|
||||
}
|
||||
|
||||
void MetaspaceUtils::print_metaspace_change(const metaspace::MetaspaceSizesSnapshot& pre_meta_values) {
|
||||
const metaspace::MetaspaceSizesSnapshot meta_values;
|
||||
// Helper for get_statistics()
|
||||
static void get_values_for(Metaspace::MetadataType mdtype, size_t* reserved, size_t* committed, size_t* used) {
|
||||
#define w2b(x) (x * sizeof(MetaWord))
|
||||
if (mdtype == Metaspace::ClassType) {
|
||||
*reserved = w2b(RunningCounters::reserved_words_class());
|
||||
*committed = w2b(RunningCounters::committed_words_class());
|
||||
*used = w2b(RunningCounters::used_words_class());
|
||||
} else {
|
||||
*reserved = w2b(RunningCounters::reserved_words_nonclass());
|
||||
*committed = w2b(RunningCounters::committed_words_nonclass());
|
||||
*used = w2b(RunningCounters::used_words_nonclass());
|
||||
}
|
||||
#undef w2b
|
||||
}
|
||||
|
||||
// Retrieve all statistics in one go; make sure the values are consistent.
|
||||
MetaspaceStats MetaspaceUtils::get_statistics(Metaspace::MetadataType mdtype) {
|
||||
|
||||
// Consistency:
|
||||
// This function reads three values (reserved, committed, used) from different counters. These counters
|
||||
// may (very rarely) be out of sync. This has been a source for intermittent test errors in the past
|
||||
// (see e.g. JDK-8237872, JDK-8151460).
|
||||
// - reserved and committed counter are updated under protection of Metaspace_lock; an inconsistency
|
||||
// between them can be the result of a dirty read.
|
||||
// - used is an atomic counter updated outside any lock range; there is no way to guarantee
|
||||
// a clean read wrt the other two values.
|
||||
// Reading these values under lock protection would would only help for the first case. Therefore
|
||||
// we don't bother and just re-read several times, then give up and correct the values.
|
||||
|
||||
size_t r = 0, c = 0, u = 0; // Note: byte values.
|
||||
get_values_for(mdtype, &r, &c, &u);
|
||||
int retries = 10;
|
||||
// If the first retrieval resulted in inconsistent values, retry a bit...
|
||||
while ((r < c || c < u) && --retries >= 0) {
|
||||
get_values_for(mdtype, &r, &c, &u);
|
||||
}
|
||||
if (c < u || r < c) { // still inconsistent.
|
||||
// ... but not endlessly. If we don't get consistent values, correct them on the fly.
|
||||
// The logic here is that we trust the used counter - its an atomic counter and whatever we see
|
||||
// must have been the truth once - and from that we reconstruct a likely set of committed/reserved
|
||||
// values.
|
||||
metaspace::InternalStats::inc_num_inconsistent_stats();
|
||||
if (c < u) {
|
||||
c = align_up(u, Metaspace::commit_alignment());
|
||||
}
|
||||
if (r < c) {
|
||||
r = align_up(c, Metaspace::reserve_alignment());
|
||||
}
|
||||
}
|
||||
return MetaspaceStats(r, c, u);
|
||||
}
|
||||
|
||||
MetaspaceCombinedStats MetaspaceUtils::get_combined_statistics() {
|
||||
return MetaspaceCombinedStats(get_statistics(Metaspace::ClassType), get_statistics(Metaspace::NonClassType));
|
||||
}
|
||||
|
||||
void MetaspaceUtils::print_metaspace_change(const MetaspaceCombinedStats& pre_meta_values) {
|
||||
// Get values now:
|
||||
const MetaspaceCombinedStats meta_values = get_combined_statistics();
|
||||
|
||||
// We print used and committed since these are the most useful at-a-glance vitals for Metaspace:
|
||||
// - used tells you how much memory is actually used for metadata
|
||||
@ -150,24 +209,23 @@ void MetaspaceUtils::print_report(outputStream* out, size_t scale) {
|
||||
void MetaspaceUtils::print_on(outputStream* out) {
|
||||
|
||||
// Used from all GCs. It first prints out totals, then, separately, the class space portion.
|
||||
|
||||
MetaspaceCombinedStats stats = get_combined_statistics();
|
||||
out->print_cr(" Metaspace "
|
||||
"used " SIZE_FORMAT "K, "
|
||||
"committed " SIZE_FORMAT "K, "
|
||||
"reserved " SIZE_FORMAT "K",
|
||||
used_bytes()/K,
|
||||
committed_bytes()/K,
|
||||
reserved_bytes()/K);
|
||||
stats.used()/K,
|
||||
stats.committed()/K,
|
||||
stats.reserved()/K);
|
||||
|
||||
if (Metaspace::using_class_space()) {
|
||||
const Metaspace::MetadataType ct = Metaspace::ClassType;
|
||||
out->print_cr(" class space "
|
||||
"used " SIZE_FORMAT "K, "
|
||||
"committed " SIZE_FORMAT "K, "
|
||||
"reserved " SIZE_FORMAT "K",
|
||||
used_bytes(ct)/K,
|
||||
committed_bytes(ct)/K,
|
||||
reserved_bytes(ct)/K);
|
||||
stats.class_space_stats().used()/K,
|
||||
stats.class_space_stats().committed()/K,
|
||||
stats.class_space_stats().reserved()/K);
|
||||
}
|
||||
}
|
||||
|
||||
@ -870,7 +928,6 @@ void Metaspace::report_metadata_oome(ClassLoaderData* loader_data, size_t word_s
|
||||
MetaspaceUtils::print_basic_report(&ls, 0);
|
||||
}
|
||||
|
||||
// TODO: this exception text may be wrong and misleading. This needs more thinking. See JDK-8252189.
|
||||
bool out_of_compressed_class_space = false;
|
||||
if (is_class_space_allocation(mdtype)) {
|
||||
ClassLoaderMetaspace* metaspace = loader_data->metaspace_non_null();
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2017, 2021 SAP SE. 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
|
||||
@ -36,10 +37,6 @@ class Mutex;
|
||||
class outputStream;
|
||||
class ReservedSpace;
|
||||
|
||||
namespace metaspace {
|
||||
class MetaspaceSizesSnapshot;
|
||||
}
|
||||
|
||||
////////////////// Metaspace ///////////////////////
|
||||
|
||||
// Namespace for important central static functions
|
||||
|
||||
@ -94,6 +94,9 @@ class InternalStats : public AllStatic {
|
||||
\
|
||||
/* Number of times we did a purge */ \
|
||||
x(num_purges) \
|
||||
\
|
||||
/* Number of times we read inconsistent stats. */ \
|
||||
x(num_inconsistent_stats) \
|
||||
|
||||
// Note: We use uintx since 32bit platforms lack 64bit atomic add; this increases
|
||||
// the possibility of counter overflows but the probability is very low for any counter
|
||||
|
||||
@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, Twitter, Inc.
|
||||
* 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 "memory/metaspace.hpp"
|
||||
#include "memory/metaspace/metaspaceSizesSnapshot.hpp"
|
||||
#include "memory/metaspaceUtils.hpp"
|
||||
|
||||
namespace metaspace {
|
||||
|
||||
MetaspaceSizesSnapshot::MetaspaceSizesSnapshot() :
|
||||
_used(MetaspaceUtils::used_bytes()),
|
||||
_committed(MetaspaceUtils::committed_bytes()),
|
||||
_non_class_used(MetaspaceUtils::used_bytes(Metaspace::NonClassType)),
|
||||
_non_class_committed(MetaspaceUtils::committed_bytes(Metaspace::NonClassType)),
|
||||
_class_used(MetaspaceUtils::used_bytes(Metaspace::ClassType)),
|
||||
_class_committed(MetaspaceUtils::committed_bytes(Metaspace::ClassType))
|
||||
{}
|
||||
|
||||
} // namespace metaspace
|
||||
@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, Twitter, Inc.
|
||||
* 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_MEMORY_METASPACE_METASPACESIZESSNAPSHOT_HPP
|
||||
#define SHARE_MEMORY_METASPACE_METASPACESIZESSNAPSHOT_HPP
|
||||
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
|
||||
namespace metaspace {
|
||||
|
||||
// Todo: clean up after jep387, see JDK-8251392
|
||||
class MetaspaceSizesSnapshot {
|
||||
public:
|
||||
MetaspaceSizesSnapshot();
|
||||
|
||||
size_t used() const { return _used; }
|
||||
size_t committed() const { return _committed; }
|
||||
size_t non_class_used() const { return _non_class_used; }
|
||||
size_t non_class_committed() const { return _non_class_committed; }
|
||||
size_t class_used() const { return _class_used; }
|
||||
size_t class_committed() const { return _class_committed; }
|
||||
|
||||
private:
|
||||
const size_t _used;
|
||||
const size_t _committed;
|
||||
const size_t _non_class_used;
|
||||
const size_t _non_class_committed;
|
||||
const size_t _class_used;
|
||||
const size_t _class_committed;
|
||||
};
|
||||
|
||||
} // namespace metaspace
|
||||
|
||||
#endif // SHARE_MEMORY_METASPACE_METASPACESIZESSNAPSHOT_HPP
|
||||
@ -25,13 +25,14 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "memory/metaspace.hpp"
|
||||
#include "memory/metaspaceCounters.hpp"
|
||||
#include "memory/metaspaceStats.hpp"
|
||||
#include "memory/metaspaceUtils.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "runtime/globals.hpp"
|
||||
#include "runtime/perfData.hpp"
|
||||
#include "utilities/exceptions.hpp"
|
||||
|
||||
class MetaspacePerfCounters: public CHeapObj<mtMetaspace> {
|
||||
class MetaspacePerfCounters {
|
||||
friend class VMStructs;
|
||||
PerfVariable* _capacity;
|
||||
PerfVariable* _used;
|
||||
@ -48,88 +49,40 @@ class MetaspacePerfCounters: public CHeapObj<mtMetaspace> {
|
||||
}
|
||||
|
||||
public:
|
||||
MetaspacePerfCounters(const char* ns, size_t min_capacity, size_t curr_capacity, size_t max_capacity, size_t used) {
|
||||
MetaspacePerfCounters() : _capacity(NULL), _used(NULL), _max_capacity(NULL) {}
|
||||
|
||||
void initialize(const char* ns) {
|
||||
assert(_capacity == NULL, "Only initialize once");
|
||||
EXCEPTION_MARK;
|
||||
ResourceMark rm;
|
||||
|
||||
create_constant(ns, "minCapacity", min_capacity, THREAD);
|
||||
_capacity = create_variable(ns, "capacity", curr_capacity, THREAD);
|
||||
_max_capacity = create_variable(ns, "maxCapacity", max_capacity, THREAD);
|
||||
_used = create_variable(ns, "used", used, THREAD);
|
||||
create_constant(ns, "minCapacity", 0, THREAD); // min_capacity makes little sense in the context of metaspace
|
||||
_capacity = create_variable(ns, "capacity", 0, THREAD);
|
||||
_max_capacity = create_variable(ns, "maxCapacity", 0, THREAD);
|
||||
_used = create_variable(ns, "used", 0, THREAD);
|
||||
}
|
||||
|
||||
void update(size_t capacity, size_t max_capacity, size_t used) {
|
||||
_capacity->set_value(capacity);
|
||||
_max_capacity->set_value(max_capacity);
|
||||
_used->set_value(used);
|
||||
void update(const MetaspaceStats& stats) {
|
||||
_capacity->set_value(stats.committed());
|
||||
_max_capacity->set_value(stats.reserved());
|
||||
_used->set_value(stats.used());
|
||||
}
|
||||
};
|
||||
|
||||
MetaspacePerfCounters* MetaspaceCounters::_perf_counters = NULL;
|
||||
|
||||
size_t MetaspaceCounters::used() {
|
||||
return MetaspaceUtils::used_bytes();
|
||||
}
|
||||
|
||||
size_t MetaspaceCounters::capacity() {
|
||||
return MetaspaceUtils::committed_bytes();
|
||||
}
|
||||
|
||||
size_t MetaspaceCounters::max_capacity() {
|
||||
return MetaspaceUtils::reserved_bytes();
|
||||
}
|
||||
static MetaspacePerfCounters g_meta_space_perf_counters; // class + nonclass
|
||||
static MetaspacePerfCounters g_class_space_perf_counters;
|
||||
|
||||
void MetaspaceCounters::initialize_performance_counters() {
|
||||
if (UsePerfData) {
|
||||
assert(_perf_counters == NULL, "Should only be initialized once");
|
||||
|
||||
size_t min_capacity = 0;
|
||||
_perf_counters = new MetaspacePerfCounters("metaspace", min_capacity,
|
||||
capacity(), max_capacity(), used());
|
||||
g_meta_space_perf_counters.initialize("metaspace");
|
||||
g_class_space_perf_counters.initialize("compressedclassspace");
|
||||
update_performance_counters();
|
||||
}
|
||||
}
|
||||
|
||||
void MetaspaceCounters::update_performance_counters() {
|
||||
if (UsePerfData) {
|
||||
assert(_perf_counters != NULL, "Should be initialized");
|
||||
|
||||
_perf_counters->update(capacity(), max_capacity(), used());
|
||||
}
|
||||
}
|
||||
|
||||
MetaspacePerfCounters* CompressedClassSpaceCounters::_perf_counters = NULL;
|
||||
|
||||
size_t CompressedClassSpaceCounters::used() {
|
||||
return MetaspaceUtils::used_bytes(Metaspace::ClassType);
|
||||
}
|
||||
|
||||
size_t CompressedClassSpaceCounters::capacity() {
|
||||
return MetaspaceUtils::committed_bytes(Metaspace::ClassType);
|
||||
}
|
||||
|
||||
size_t CompressedClassSpaceCounters::max_capacity() {
|
||||
return MetaspaceUtils::reserved_bytes(Metaspace::ClassType);
|
||||
}
|
||||
|
||||
void CompressedClassSpaceCounters::update_performance_counters() {
|
||||
if (UsePerfData && UseCompressedClassPointers) {
|
||||
assert(_perf_counters != NULL, "Should be initialized");
|
||||
|
||||
_perf_counters->update(capacity(), max_capacity(), used());
|
||||
}
|
||||
}
|
||||
|
||||
void CompressedClassSpaceCounters::initialize_performance_counters() {
|
||||
if (UsePerfData) {
|
||||
assert(_perf_counters == NULL, "Should only be initialized once");
|
||||
const char* ns = "compressedclassspace";
|
||||
|
||||
if (UseCompressedClassPointers) {
|
||||
size_t min_capacity = 0;
|
||||
_perf_counters = new MetaspacePerfCounters(ns, min_capacity, capacity(),
|
||||
max_capacity(), used());
|
||||
} else {
|
||||
_perf_counters = new MetaspacePerfCounters(ns, 0, 0, 0, 0);
|
||||
}
|
||||
g_meta_space_perf_counters.update(MetaspaceUtils::get_combined_statistics());
|
||||
g_class_space_perf_counters.update(MetaspaceUtils::get_statistics(Metaspace::ClassType));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021 SAP SE. 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
|
||||
@ -27,26 +28,9 @@
|
||||
|
||||
#include "memory/allocation.hpp"
|
||||
|
||||
class MetaspacePerfCounters;
|
||||
// Perf Counters for Metaspace
|
||||
|
||||
// Todo: clean up after jep387, see JDK-8251392
|
||||
class MetaspaceCounters: public AllStatic {
|
||||
static MetaspacePerfCounters* _perf_counters;
|
||||
static size_t used();
|
||||
static size_t capacity();
|
||||
static size_t max_capacity();
|
||||
|
||||
public:
|
||||
static void initialize_performance_counters();
|
||||
static void update_performance_counters();
|
||||
};
|
||||
|
||||
class CompressedClassSpaceCounters: public AllStatic {
|
||||
static MetaspacePerfCounters* _perf_counters;
|
||||
static size_t used();
|
||||
static size_t capacity();
|
||||
static size_t max_capacity();
|
||||
|
||||
public:
|
||||
static void initialize_performance_counters();
|
||||
static void update_performance_counters();
|
||||
|
||||
76
src/hotspot/share/memory/metaspaceStats.hpp
Normal file
76
src/hotspot/share/memory/metaspaceStats.hpp
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021 SAP SE. 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_MEMORY_METASPACESTATS_HPP
|
||||
#define SHARE_MEMORY_METASPACESTATS_HPP
|
||||
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
|
||||
// Data holder classes for metaspace statistics.
|
||||
//
|
||||
// - MetaspaceStats: keeps reserved, committed and used byte counters;
|
||||
// retrieve with MetaspaceUtils::get_statistics(MetadataType) for either class space
|
||||
// or non-class space
|
||||
//
|
||||
// - MetaspaceCombinedStats: keeps reserved, committed and used byte counters, seperately for both class- and non-class-space;
|
||||
// retrieve with MetaspaceUtils::get_combined_statistics()
|
||||
|
||||
// (Note: just for NMT these objects need to be mutable)
|
||||
|
||||
class MetaspaceStats {
|
||||
size_t _reserved;
|
||||
size_t _committed;
|
||||
size_t _used;
|
||||
public:
|
||||
MetaspaceStats() : _reserved(0), _committed(0), _used(0) {}
|
||||
MetaspaceStats(size_t r, size_t c, size_t u) : _reserved(r), _committed(c), _used(u) {}
|
||||
size_t used() const { return _used; }
|
||||
size_t committed() const { return _committed; }
|
||||
size_t reserved() const { return _reserved; }
|
||||
};
|
||||
|
||||
// Class holds combined statistics for both non-class and class space.
|
||||
class MetaspaceCombinedStats : public MetaspaceStats {
|
||||
MetaspaceStats _cstats; // class space stats
|
||||
MetaspaceStats _ncstats; // non-class space stats
|
||||
public:
|
||||
MetaspaceCombinedStats() {}
|
||||
MetaspaceCombinedStats(const MetaspaceStats& cstats, const MetaspaceStats& ncstats) :
|
||||
MetaspaceStats(cstats.reserved() + ncstats.reserved(),
|
||||
cstats.committed() + ncstats.committed(),
|
||||
cstats.used() + ncstats.used()),
|
||||
_cstats(cstats), _ncstats(ncstats)
|
||||
{}
|
||||
|
||||
const MetaspaceStats& class_space_stats() const { return _cstats; }
|
||||
const MetaspaceStats& non_class_space_stats() const { return _ncstats; }
|
||||
size_t class_used() const { return _cstats.used(); }
|
||||
size_t class_committed() const { return _cstats.committed(); }
|
||||
size_t class_reserved() const { return _cstats.reserved(); }
|
||||
size_t non_class_used() const { return _ncstats.used(); }
|
||||
size_t non_class_committed() const { return _ncstats.committed(); }
|
||||
size_t non_class_reserved() const { return _ncstats.reserved(); }
|
||||
};
|
||||
|
||||
#endif // SHARE_MEMORY_METASPACESTATS_HPP
|
||||
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021 SAP SE. 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
|
||||
@ -26,6 +27,7 @@
|
||||
|
||||
#include "memory/metaspace.hpp"
|
||||
#include "memory/metaspaceChunkFreeListSummary.hpp"
|
||||
#include "memory/metaspaceStats.hpp"
|
||||
|
||||
class outputStream;
|
||||
|
||||
@ -115,13 +117,17 @@ public:
|
||||
static size_t reserved_bytes() { return reserved_words() * BytesPerWord; }
|
||||
static size_t reserved_bytes(Metaspace::MetadataType mdtype) { return reserved_words(mdtype) * BytesPerWord; }
|
||||
|
||||
// Retrieve all statistics in one go; make sure the values are consistent.
|
||||
static MetaspaceStats get_statistics(Metaspace::MetadataType mdtype);
|
||||
static MetaspaceCombinedStats get_combined_statistics();
|
||||
|
||||
// (See JDK-8251342). Implement or Consolidate.
|
||||
static MetaspaceChunkFreeListSummary chunk_free_list_summary(Metaspace::MetadataType mdtype) {
|
||||
return MetaspaceChunkFreeListSummary(0,0,0,0,0,0,0,0);
|
||||
}
|
||||
|
||||
// Log change in used metadata.
|
||||
static void print_metaspace_change(const metaspace::MetaspaceSizesSnapshot& pre_meta_values);
|
||||
static void print_metaspace_change(const MetaspaceCombinedStats& pre_meta_values);
|
||||
|
||||
// This will print out a basic metaspace usage report but
|
||||
// unlike print_report() is guaranteed not to lock or to walk the CLDG.
|
||||
|
||||
@ -752,7 +752,6 @@ jint universe_init() {
|
||||
|
||||
// Initialize performance counters for metaspaces
|
||||
MetaspaceCounters::initialize_performance_counters();
|
||||
CompressedClassSpaceCounters::initialize_performance_counters();
|
||||
|
||||
// Checks 'AfterMemoryInit' constraints.
|
||||
if (!JVMFlagLimit::check_all_constraints(JVMFlagConstraintPhase::AfterMemoryInit)) {
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
|
||||
#include "classfile/classLoaderDataGraph.inline.hpp"
|
||||
#include "memory/allocation.hpp"
|
||||
#include "memory/metaspaceUtils.hpp"
|
||||
#include "runtime/safepoint.hpp"
|
||||
#include "runtime/thread.inline.hpp"
|
||||
#include "services/memBaseline.hpp"
|
||||
@ -147,7 +148,7 @@ class VirtualMemoryAllocationWalker : public VirtualMemoryWalker {
|
||||
bool MemBaseline::baseline_summary() {
|
||||
MallocMemorySummary::snapshot(&_malloc_memory_snapshot);
|
||||
VirtualMemorySummary::snapshot(&_virtual_memory_snapshot);
|
||||
MetaspaceSnapshot::snapshot(_metaspace_snapshot);
|
||||
_metaspace_stats = MetaspaceUtils::get_combined_statistics();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
|
||||
#if INCLUDE_NMT
|
||||
|
||||
#include "memory/metaspaceStats.hpp"
|
||||
#include "runtime/mutex.hpp"
|
||||
#include "services/mallocSiteTable.hpp"
|
||||
#include "services/mallocTracker.hpp"
|
||||
@ -61,7 +62,7 @@ class MemBaseline {
|
||||
// Summary information
|
||||
MallocMemorySnapshot _malloc_memory_snapshot;
|
||||
VirtualMemorySnapshot _virtual_memory_snapshot;
|
||||
MetaspaceSnapshot _metaspace_snapshot;
|
||||
MetaspaceCombinedStats _metaspace_stats;
|
||||
|
||||
size_t _instance_class_count;
|
||||
size_t _array_class_count;
|
||||
@ -101,8 +102,8 @@ class MemBaseline {
|
||||
return &_virtual_memory_snapshot;
|
||||
}
|
||||
|
||||
MetaspaceSnapshot* metaspace_snapshot() {
|
||||
return &_metaspace_snapshot;
|
||||
const MetaspaceCombinedStats& metaspace_stats() const {
|
||||
return _metaspace_stats;
|
||||
}
|
||||
|
||||
MallocSiteIterator malloc_sites(SortingOrder order);
|
||||
|
||||
@ -223,24 +223,18 @@ void MemSummaryReporter::report_metadata(Metaspace::MetadataType type) const {
|
||||
|
||||
outputStream* out = output();
|
||||
const char* scale = current_scale();
|
||||
size_t committed = MetaspaceUtils::committed_bytes(type);
|
||||
size_t used = MetaspaceUtils::used_bytes(type);
|
||||
const MetaspaceStats stats = MetaspaceUtils::get_statistics(type);
|
||||
|
||||
// The answer to "what is free" in metaspace is complex and cannot be answered with a single number.
|
||||
// Free as in available to all loaders? Free, pinned to one loader? For now, keep it simple.
|
||||
size_t free = committed - used;
|
||||
|
||||
assert(committed >= used + free, "Sanity");
|
||||
size_t waste = committed - (used + free);
|
||||
size_t waste = stats.committed() - stats.used();
|
||||
float waste_percentage = stats.committed() > 0 ? (((float)waste * 100)/stats.committed()) : 0.0f;
|
||||
|
||||
out->print_cr("%27s ( %s)", " ", name);
|
||||
out->print("%27s ( ", " ");
|
||||
print_total(MetaspaceUtils::reserved_bytes(type), committed);
|
||||
print_total(stats.reserved(), stats.committed());
|
||||
out->print_cr(")");
|
||||
out->print_cr("%27s ( used=" SIZE_FORMAT "%s)", " ", amount_in_current_scale(used), scale);
|
||||
out->print_cr("%27s ( free=" SIZE_FORMAT "%s)", " ", amount_in_current_scale(free), scale);
|
||||
out->print_cr("%27s ( used=" SIZE_FORMAT "%s)", " ", amount_in_current_scale(stats.used()), scale);
|
||||
out->print_cr("%27s ( waste=" SIZE_FORMAT "%s =%2.2f%%)", " ", amount_in_current_scale(waste),
|
||||
scale, ((float)waste * 100)/committed);
|
||||
scale, waste_percentage);
|
||||
}
|
||||
|
||||
void MemDetailReporter::report_detail() {
|
||||
@ -408,10 +402,10 @@ void MemSummaryDiffReporter::report_diff() {
|
||||
diff_summary_of_type(flag,
|
||||
_early_baseline.malloc_memory(flag),
|
||||
_early_baseline.virtual_memory(flag),
|
||||
_early_baseline.metaspace_snapshot(),
|
||||
_early_baseline.metaspace_stats(),
|
||||
_current_baseline.malloc_memory(flag),
|
||||
_current_baseline.virtual_memory(flag),
|
||||
_current_baseline.metaspace_snapshot());
|
||||
_current_baseline.metaspace_stats());
|
||||
}
|
||||
}
|
||||
|
||||
@ -474,9 +468,9 @@ void MemSummaryDiffReporter::print_virtual_memory_diff(size_t current_reserved,
|
||||
|
||||
void MemSummaryDiffReporter::diff_summary_of_type(MEMFLAGS flag,
|
||||
const MallocMemory* early_malloc, const VirtualMemory* early_vm,
|
||||
const MetaspaceSnapshot* early_ms,
|
||||
const MetaspaceCombinedStats& early_ms,
|
||||
const MallocMemory* current_malloc, const VirtualMemory* current_vm,
|
||||
const MetaspaceSnapshot* current_ms) const {
|
||||
const MetaspaceCombinedStats& current_ms) const {
|
||||
|
||||
outputStream* out = output();
|
||||
const char* scale = current_scale();
|
||||
@ -615,70 +609,54 @@ void MemSummaryDiffReporter::diff_summary_of_type(MEMFLAGS flag,
|
||||
}
|
||||
out->print_cr(")");
|
||||
} else if (flag == mtClass) {
|
||||
assert(current_ms != NULL && early_ms != NULL, "Sanity");
|
||||
print_metaspace_diff(current_ms, early_ms);
|
||||
}
|
||||
out->print_cr(" ");
|
||||
}
|
||||
}
|
||||
|
||||
void MemSummaryDiffReporter::print_metaspace_diff(const MetaspaceSnapshot* current_ms,
|
||||
const MetaspaceSnapshot* early_ms) const {
|
||||
print_metaspace_diff(Metaspace::NonClassType, current_ms, early_ms);
|
||||
void MemSummaryDiffReporter::print_metaspace_diff(const MetaspaceCombinedStats& current_ms,
|
||||
const MetaspaceCombinedStats& early_ms) const {
|
||||
print_metaspace_diff("Metadata", current_ms.non_class_space_stats(), early_ms.non_class_space_stats());
|
||||
if (Metaspace::using_class_space()) {
|
||||
print_metaspace_diff(Metaspace::ClassType, current_ms, early_ms);
|
||||
print_metaspace_diff("Class space", current_ms.class_space_stats(), early_ms.class_space_stats());
|
||||
}
|
||||
}
|
||||
|
||||
void MemSummaryDiffReporter::print_metaspace_diff(Metaspace::MetadataType type,
|
||||
const MetaspaceSnapshot* current_ms,
|
||||
const MetaspaceSnapshot* early_ms) const {
|
||||
const char* name = (type == Metaspace::NonClassType) ?
|
||||
"Metadata: " : "Class space:";
|
||||
|
||||
void MemSummaryDiffReporter::print_metaspace_diff(const char* header,
|
||||
const MetaspaceStats& current_stats,
|
||||
const MetaspaceStats& early_stats) const {
|
||||
outputStream* out = output();
|
||||
const char* scale = current_scale();
|
||||
|
||||
out->print_cr("%27s ( %s)", " ", name);
|
||||
out->print_cr("%27s: ( %s)", " ", header);
|
||||
out->print("%27s ( ", " ");
|
||||
print_virtual_memory_diff(current_ms->reserved_in_bytes(type),
|
||||
current_ms->committed_in_bytes(type),
|
||||
early_ms->reserved_in_bytes(type),
|
||||
early_ms->committed_in_bytes(type));
|
||||
print_virtual_memory_diff(current_stats.reserved(),
|
||||
current_stats.committed(),
|
||||
early_stats.reserved(),
|
||||
early_stats.committed());
|
||||
out->print_cr(")");
|
||||
|
||||
long diff_used = diff_in_current_scale(current_ms->used_in_bytes(type),
|
||||
early_ms->used_in_bytes(type));
|
||||
long diff_free = diff_in_current_scale(current_ms->free_in_bytes(type),
|
||||
early_ms->free_in_bytes(type));
|
||||
long diff_used = diff_in_current_scale(current_stats.used(),
|
||||
early_stats.used());
|
||||
|
||||
size_t current_waste = current_ms->committed_in_bytes(type)
|
||||
- (current_ms->used_in_bytes(type) + current_ms->free_in_bytes(type));
|
||||
size_t early_waste = early_ms->committed_in_bytes(type)
|
||||
- (early_ms->used_in_bytes(type) + early_ms->free_in_bytes(type));
|
||||
size_t current_waste = current_stats.committed() - current_stats.used();
|
||||
size_t early_waste = early_stats.committed() - early_stats.used();
|
||||
long diff_waste = diff_in_current_scale(current_waste, early_waste);
|
||||
|
||||
// Diff used
|
||||
out->print("%27s ( used=" SIZE_FORMAT "%s", " ",
|
||||
amount_in_current_scale(current_ms->used_in_bytes(type)), scale);
|
||||
amount_in_current_scale(current_stats.used()), scale);
|
||||
if (diff_used != 0) {
|
||||
out->print(" %+ld%s", diff_used, scale);
|
||||
}
|
||||
out->print_cr(")");
|
||||
|
||||
// Diff free
|
||||
out->print("%27s ( free=" SIZE_FORMAT "%s", " ",
|
||||
amount_in_current_scale(current_ms->free_in_bytes(type)), scale);
|
||||
if (diff_free != 0) {
|
||||
out->print(" %+ld%s", diff_free, scale);
|
||||
}
|
||||
out->print_cr(")");
|
||||
|
||||
|
||||
// Diff waste
|
||||
const float waste_percentage = current_stats.committed() == 0 ? 0.0f :
|
||||
(current_waste * 100.0f) / current_stats.committed();
|
||||
out->print("%27s ( waste=" SIZE_FORMAT "%s =%2.2f%%", " ",
|
||||
amount_in_current_scale(current_waste), scale,
|
||||
((float)current_waste * 100) / current_ms->committed_in_bytes(type));
|
||||
amount_in_current_scale(current_waste), scale, waste_percentage);
|
||||
if (diff_waste != 0) {
|
||||
out->print(" %+ld%s", diff_waste, scale);
|
||||
}
|
||||
|
||||
@ -180,9 +180,9 @@ class MemSummaryDiffReporter : public MemReporterBase {
|
||||
// report the comparison of each memory type
|
||||
void diff_summary_of_type(MEMFLAGS type,
|
||||
const MallocMemory* early_malloc, const VirtualMemory* early_vm,
|
||||
const MetaspaceSnapshot* early_ms,
|
||||
const MetaspaceCombinedStats& early_ms,
|
||||
const MallocMemory* current_malloc, const VirtualMemory* current_vm,
|
||||
const MetaspaceSnapshot* current_ms) const;
|
||||
const MetaspaceCombinedStats& current_ms) const;
|
||||
|
||||
protected:
|
||||
void print_malloc_diff(size_t current_amount, size_t current_count,
|
||||
@ -192,10 +192,11 @@ class MemSummaryDiffReporter : public MemReporterBase {
|
||||
void print_arena_diff(size_t current_amount, size_t current_count,
|
||||
size_t early_amount, size_t early_count) const;
|
||||
|
||||
void print_metaspace_diff(const MetaspaceSnapshot* current_ms,
|
||||
const MetaspaceSnapshot* early_ms) const;
|
||||
void print_metaspace_diff(Metaspace::MetadataType type,
|
||||
const MetaspaceSnapshot* current_ms, const MetaspaceSnapshot* early_ms) const;
|
||||
void print_metaspace_diff(const MetaspaceCombinedStats& current_ms,
|
||||
const MetaspaceCombinedStats& early_ms) const;
|
||||
void print_metaspace_diff(const char* header,
|
||||
const MetaspaceStats& current_ms,
|
||||
const MetaspaceStats& early_ms) const;
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@ -188,8 +188,8 @@ MetaspacePool::MetaspacePool() :
|
||||
MemoryPool("Metaspace", NonHeap, 0, calculate_max_size(), true, false) { }
|
||||
|
||||
MemoryUsage MetaspacePool::get_memory_usage() {
|
||||
size_t committed = MetaspaceUtils::committed_bytes();
|
||||
return MemoryUsage(initial_size(), used_in_bytes(), committed, max_size());
|
||||
MetaspaceCombinedStats stats = MetaspaceUtils::get_combined_statistics();
|
||||
return MemoryUsage(initial_size(), stats.used(), stats.committed(), max_size());
|
||||
}
|
||||
|
||||
size_t MetaspacePool::used_in_bytes() {
|
||||
@ -209,6 +209,6 @@ size_t CompressedKlassSpacePool::used_in_bytes() {
|
||||
}
|
||||
|
||||
MemoryUsage CompressedKlassSpacePool::get_memory_usage() {
|
||||
size_t committed = MetaspaceUtils::committed_bytes(Metaspace::ClassType);
|
||||
return MemoryUsage(initial_size(), used_in_bytes(), committed, max_size());
|
||||
MetaspaceStats stats = MetaspaceUtils::get_statistics(Metaspace::ClassType);
|
||||
return MemoryUsage(initial_size(), stats.used(), stats.committed(), max_size());
|
||||
}
|
||||
|
||||
@ -23,8 +23,8 @@
|
||||
*/
|
||||
#include "precompiled.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/metaspace.hpp"
|
||||
#include "memory/metaspaceUtils.hpp"
|
||||
#include "memory/metaspaceStats.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/threadCritical.hpp"
|
||||
#include "services/memTracker.hpp"
|
||||
@ -693,34 +693,3 @@ bool VirtualMemoryTracker::transition(NMT_TrackingLevel from, NMT_TrackingLevel
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Metaspace Support
|
||||
MetaspaceSnapshot::MetaspaceSnapshot() {
|
||||
for (int index = (int)Metaspace::ClassType; index < (int)Metaspace::MetadataTypeCount; index ++) {
|
||||
Metaspace::MetadataType type = (Metaspace::MetadataType)index;
|
||||
assert_valid_metadata_type(type);
|
||||
_reserved_in_bytes[type] = 0;
|
||||
_committed_in_bytes[type] = 0;
|
||||
_used_in_bytes[type] = 0;
|
||||
_free_in_bytes[type] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void MetaspaceSnapshot::snapshot(Metaspace::MetadataType type, MetaspaceSnapshot& mss) {
|
||||
assert_valid_metadata_type(type);
|
||||
|
||||
mss._reserved_in_bytes[type] = MetaspaceUtils::reserved_bytes(type);
|
||||
mss._committed_in_bytes[type] = MetaspaceUtils::committed_bytes(type);
|
||||
mss._used_in_bytes[type] = MetaspaceUtils::used_bytes(type);
|
||||
|
||||
// The answer to "what is free" in metaspace is complex and cannot be answered with a single number.
|
||||
// Free as in available to all loaders? Free, pinned to one loader? For now, keep it simple.
|
||||
mss._free_in_bytes[type] = mss._committed_in_bytes[type] - mss._used_in_bytes[type];
|
||||
}
|
||||
|
||||
void MetaspaceSnapshot::snapshot(MetaspaceSnapshot& mss) {
|
||||
snapshot(Metaspace::NonClassType, mss);
|
||||
if (Metaspace::using_class_space()) {
|
||||
snapshot(Metaspace::ClassType, mss);
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,7 +28,8 @@
|
||||
#if INCLUDE_NMT
|
||||
|
||||
#include "memory/allocation.hpp"
|
||||
#include "memory/metaspace.hpp"
|
||||
#include "memory/metaspace.hpp" // For MetadataType
|
||||
#include "memory/metaspaceStats.hpp"
|
||||
#include "services/allocationSite.hpp"
|
||||
#include "services/nmtCommon.hpp"
|
||||
#include "utilities/linkedlist.hpp"
|
||||
@ -398,32 +399,6 @@ class VirtualMemoryTracker : AllStatic {
|
||||
static SortedLinkedList<ReservedMemoryRegion, compare_reserved_region_base>* _reserved_regions;
|
||||
};
|
||||
|
||||
// Todo: clean up after jep387, see JDK-8251392
|
||||
class MetaspaceSnapshot : public ResourceObj {
|
||||
private:
|
||||
size_t _reserved_in_bytes[Metaspace::MetadataTypeCount];
|
||||
size_t _committed_in_bytes[Metaspace::MetadataTypeCount];
|
||||
size_t _used_in_bytes[Metaspace::MetadataTypeCount];
|
||||
size_t _free_in_bytes[Metaspace::MetadataTypeCount];
|
||||
|
||||
public:
|
||||
MetaspaceSnapshot();
|
||||
size_t reserved_in_bytes(Metaspace::MetadataType type) const { assert_valid_metadata_type(type); return _reserved_in_bytes[type]; }
|
||||
size_t committed_in_bytes(Metaspace::MetadataType type) const { assert_valid_metadata_type(type); return _committed_in_bytes[type]; }
|
||||
size_t used_in_bytes(Metaspace::MetadataType type) const { assert_valid_metadata_type(type); return _used_in_bytes[type]; }
|
||||
size_t free_in_bytes(Metaspace::MetadataType type) const { assert_valid_metadata_type(type); return _free_in_bytes[type]; }
|
||||
|
||||
static void snapshot(MetaspaceSnapshot& s);
|
||||
|
||||
private:
|
||||
static void snapshot(Metaspace::MetadataType type, MetaspaceSnapshot& s);
|
||||
|
||||
static void assert_valid_metadata_type(Metaspace::MetadataType type) {
|
||||
assert(type == Metaspace::ClassType || type == Metaspace::NonClassType,
|
||||
"Invalid metadata type");
|
||||
}
|
||||
};
|
||||
|
||||
#endif // INCLUDE_NMT
|
||||
|
||||
#endif // SHARE_SERVICES_VIRTUALMEMORYTRACKER_HPP
|
||||
|
||||
@ -88,3 +88,31 @@ TEST_VM(MetaspaceUtils, non_compressed_class_pointers) {
|
||||
EXPECT_EQ(reserved_class, 0UL);
|
||||
}
|
||||
|
||||
static void check_metaspace_stats_are_consistent(const MetaspaceStats& stats) {
|
||||
EXPECT_LT(stats.committed(), stats.reserved());
|
||||
EXPECT_LT(stats.used(), stats.committed());
|
||||
}
|
||||
|
||||
static void check_metaspace_stats_are_not_null(const MetaspaceStats& stats) {
|
||||
EXPECT_GT(stats.reserved(), 0UL);
|
||||
EXPECT_GT(stats.committed(), 0UL);
|
||||
EXPECT_GT(stats.used(), 0UL);
|
||||
}
|
||||
|
||||
TEST_VM(MetaspaceUtils, get_statistics) {
|
||||
MetaspaceCombinedStats combined_stats = MetaspaceUtils::get_combined_statistics();
|
||||
check_metaspace_stats_are_not_null(combined_stats);
|
||||
check_metaspace_stats_are_consistent(combined_stats);
|
||||
check_metaspace_stats_are_not_null(combined_stats.non_class_space_stats());
|
||||
check_metaspace_stats_are_consistent(combined_stats.non_class_space_stats());
|
||||
|
||||
if (UseCompressedClassPointers) {
|
||||
check_metaspace_stats_are_not_null(combined_stats.class_space_stats());
|
||||
check_metaspace_stats_are_consistent(combined_stats.class_space_stats());
|
||||
} else {
|
||||
// if we don't have a class space, combined stats should equal non-class stats
|
||||
EXPECT_EQ(combined_stats.non_class_space_stats().reserved(), combined_stats.reserved());
|
||||
EXPECT_EQ(combined_stats.non_class_space_stats().committed(), combined_stats.committed());
|
||||
EXPECT_EQ(combined_stats.non_class_space_stats().used(), combined_stats.used());
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user