mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-21 11:34:38 +02:00
8014659: NPG: performance counters for compressed klass space
Reviewed-by: mgerdin, coleenp, hseigel, jmasa, ctornqvi
This commit is contained in:
parent
2c28ff340a
commit
3ea9481c2f
16 changed files with 1284 additions and 126 deletions
|
@ -1211,6 +1211,7 @@ void GenCollectedHeap::gc_epilogue(bool full) {
|
|||
}
|
||||
|
||||
MetaspaceCounters::update_performance_counters();
|
||||
CompressedClassSpaceCounters::update_performance_counters();
|
||||
|
||||
always_do_update_barrier = UseConcMarkSweepGC;
|
||||
};
|
||||
|
|
|
@ -2480,16 +2480,13 @@ void SpaceManager::mangle_freed_chunks() {
|
|||
size_t MetaspaceAux::_allocated_capacity_words[] = {0, 0};
|
||||
size_t MetaspaceAux::_allocated_used_words[] = {0, 0};
|
||||
|
||||
size_t MetaspaceAux::free_bytes(Metaspace::MetadataType mdtype) {
|
||||
VirtualSpaceList* list = Metaspace::get_space_list(mdtype);
|
||||
return list == NULL ? 0 : list->free_bytes();
|
||||
}
|
||||
|
||||
size_t MetaspaceAux::free_bytes() {
|
||||
size_t result = 0;
|
||||
if (Metaspace::using_class_space() &&
|
||||
(Metaspace::class_space_list() != NULL)) {
|
||||
result = result + Metaspace::class_space_list()->free_bytes();
|
||||
}
|
||||
if (Metaspace::space_list() != NULL) {
|
||||
result = result + Metaspace::space_list()->free_bytes();
|
||||
}
|
||||
return result;
|
||||
return free_bytes(Metaspace::ClassType) + free_bytes(Metaspace::NonClassType);
|
||||
}
|
||||
|
||||
void MetaspaceAux::dec_capacity(Metaspace::MetadataType mdtype, size_t words) {
|
||||
|
@ -2571,23 +2568,18 @@ size_t MetaspaceAux::capacity_bytes_slow(Metaspace::MetadataType mdtype) {
|
|||
}
|
||||
|
||||
size_t MetaspaceAux::reserved_in_bytes(Metaspace::MetadataType mdtype) {
|
||||
if (mdtype == Metaspace::ClassType) {
|
||||
return Metaspace::using_class_space() ?
|
||||
Metaspace::class_space_list()->virtual_space_total() * BytesPerWord : 0;
|
||||
} else {
|
||||
return Metaspace::space_list()->virtual_space_total() * BytesPerWord;
|
||||
}
|
||||
VirtualSpaceList* list = Metaspace::get_space_list(mdtype);
|
||||
return list == NULL ? 0 : list->virtual_space_total();
|
||||
}
|
||||
|
||||
size_t MetaspaceAux::min_chunk_size() { return Metaspace::first_chunk_word_size(); }
|
||||
|
||||
size_t MetaspaceAux::free_chunks_total(Metaspace::MetadataType mdtype) {
|
||||
if ((mdtype == Metaspace::ClassType) && !Metaspace::using_class_space()) {
|
||||
VirtualSpaceList* list = Metaspace::get_space_list(mdtype);
|
||||
if (list == NULL) {
|
||||
return 0;
|
||||
}
|
||||
ChunkManager* chunk = (mdtype == Metaspace::ClassType) ?
|
||||
Metaspace::class_space_list()->chunk_manager() :
|
||||
Metaspace::space_list()->chunk_manager();
|
||||
ChunkManager* chunk = list->chunk_manager();
|
||||
chunk->slow_verify();
|
||||
return chunk->free_chunks_total();
|
||||
}
|
||||
|
|
|
@ -136,6 +136,10 @@ class Metaspace : public CHeapObj<mtClass> {
|
|||
|
||||
static VirtualSpaceList* space_list() { return _space_list; }
|
||||
static VirtualSpaceList* class_space_list() { return _class_space_list; }
|
||||
static VirtualSpaceList* get_space_list(MetadataType mdtype) {
|
||||
assert(mdtype != MetadataTypeCount, "MetadaTypeCount can't be used as mdtype");
|
||||
return mdtype == ClassType ? class_space_list() : space_list();
|
||||
}
|
||||
|
||||
// This is used by DumpSharedSpaces only, where only _vsm is used. So we will
|
||||
// maintain a single list for now.
|
||||
|
@ -218,7 +222,6 @@ class Metaspace : public CHeapObj<mtClass> {
|
|||
|
||||
class MetaspaceAux : AllStatic {
|
||||
static size_t free_chunks_total(Metaspace::MetadataType mdtype);
|
||||
static size_t free_chunks_total_in_bytes(Metaspace::MetadataType mdtype);
|
||||
|
||||
public:
|
||||
// Statistics for class space and data space in metaspace.
|
||||
|
@ -262,6 +265,7 @@ class MetaspaceAux : AllStatic {
|
|||
// Used by MetaspaceCounters
|
||||
static size_t free_chunks_total();
|
||||
static size_t free_chunks_total_in_bytes();
|
||||
static size_t free_chunks_total_in_bytes(Metaspace::MetadataType mdtype);
|
||||
|
||||
static size_t allocated_capacity_words(Metaspace::MetadataType mdtype) {
|
||||
return _allocated_capacity_words[mdtype];
|
||||
|
@ -294,6 +298,7 @@ class MetaspaceAux : AllStatic {
|
|||
}
|
||||
|
||||
static size_t free_bytes();
|
||||
static size_t free_bytes(Metaspace::MetadataType mdtype);
|
||||
|
||||
// Total capacity in all Metaspaces
|
||||
static size_t capacity_bytes_slow() {
|
||||
|
|
|
@ -25,11 +25,47 @@
|
|||
#include "precompiled.hpp"
|
||||
#include "memory/metaspaceCounters.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "runtime/globals.hpp"
|
||||
#include "runtime/perfData.hpp"
|
||||
#include "utilities/exceptions.hpp"
|
||||
|
||||
MetaspaceCounters* MetaspaceCounters::_metaspace_counters = NULL;
|
||||
class MetaspacePerfCounters: public CHeapObj<mtInternal> {
|
||||
friend class VMStructs;
|
||||
PerfVariable* _capacity;
|
||||
PerfVariable* _used;
|
||||
PerfVariable* _max_capacity;
|
||||
|
||||
size_t MetaspaceCounters::calc_total_capacity() {
|
||||
PerfVariable* create_variable(const char *ns, const char *name, size_t value, TRAPS) {
|
||||
const char *path = PerfDataManager::counter_name(ns, name);
|
||||
return PerfDataManager::create_variable(SUN_GC, path, PerfData::U_Bytes, value, THREAD);
|
||||
}
|
||||
|
||||
void create_constant(const char *ns, const char *name, size_t value, TRAPS) {
|
||||
const char *path = PerfDataManager::counter_name(ns, name);
|
||||
PerfDataManager::create_constant(SUN_GC, path, PerfData::U_Bytes, value, THREAD);
|
||||
}
|
||||
|
||||
public:
|
||||
MetaspacePerfCounters(const char* ns, size_t min_capacity, size_t curr_capacity, size_t max_capacity, size_t used) {
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
MetaspacePerfCounters* MetaspaceCounters::_perf_counters = NULL;
|
||||
|
||||
size_t MetaspaceCounters::calculate_capacity() {
|
||||
// The total capacity is the sum of
|
||||
// 1) capacity of Metachunks in use by all Metaspaces
|
||||
// 2) unused space at the end of each Metachunk
|
||||
|
@ -39,95 +75,65 @@ size_t MetaspaceCounters::calc_total_capacity() {
|
|||
return total_capacity;
|
||||
}
|
||||
|
||||
MetaspaceCounters::MetaspaceCounters() :
|
||||
_capacity(NULL),
|
||||
_used(NULL),
|
||||
_max_capacity(NULL) {
|
||||
if (UsePerfData) {
|
||||
size_t min_capacity = MetaspaceAux::min_chunk_size();
|
||||
size_t max_capacity = MetaspaceAux::reserved_in_bytes();
|
||||
size_t curr_capacity = calc_total_capacity();
|
||||
size_t used = MetaspaceAux::allocated_used_bytes();
|
||||
|
||||
initialize(min_capacity, max_capacity, curr_capacity, used);
|
||||
}
|
||||
}
|
||||
|
||||
static PerfVariable* create_ms_variable(const char *ns,
|
||||
const char *name,
|
||||
size_t value,
|
||||
TRAPS) {
|
||||
const char *path = PerfDataManager::counter_name(ns, name);
|
||||
PerfVariable *result =
|
||||
PerfDataManager::create_variable(SUN_GC, path, PerfData::U_Bytes, value,
|
||||
CHECK_NULL);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void create_ms_constant(const char *ns,
|
||||
const char *name,
|
||||
size_t value,
|
||||
TRAPS) {
|
||||
const char *path = PerfDataManager::counter_name(ns, name);
|
||||
PerfDataManager::create_constant(SUN_GC, path, PerfData::U_Bytes, value, CHECK);
|
||||
}
|
||||
|
||||
void MetaspaceCounters::initialize(size_t min_capacity,
|
||||
size_t max_capacity,
|
||||
size_t curr_capacity,
|
||||
size_t used) {
|
||||
|
||||
if (UsePerfData) {
|
||||
EXCEPTION_MARK;
|
||||
ResourceMark rm;
|
||||
|
||||
const char *ms = "metaspace";
|
||||
|
||||
create_ms_constant(ms, "minCapacity", min_capacity, CHECK);
|
||||
_max_capacity = create_ms_variable(ms, "maxCapacity", max_capacity, CHECK);
|
||||
_capacity = create_ms_variable(ms, "capacity", curr_capacity, CHECK);
|
||||
_used = create_ms_variable(ms, "used", used, CHECK);
|
||||
}
|
||||
}
|
||||
|
||||
void MetaspaceCounters::update_capacity() {
|
||||
assert(UsePerfData, "Should not be called unless being used");
|
||||
size_t total_capacity = calc_total_capacity();
|
||||
_capacity->set_value(total_capacity);
|
||||
}
|
||||
|
||||
void MetaspaceCounters::update_used() {
|
||||
assert(UsePerfData, "Should not be called unless being used");
|
||||
size_t used_in_bytes = MetaspaceAux::allocated_used_bytes();
|
||||
_used->set_value(used_in_bytes);
|
||||
}
|
||||
|
||||
void MetaspaceCounters::update_max_capacity() {
|
||||
assert(UsePerfData, "Should not be called unless being used");
|
||||
assert(_max_capacity != NULL, "Should be initialized");
|
||||
size_t reserved_in_bytes = MetaspaceAux::reserved_in_bytes();
|
||||
_max_capacity->set_value(reserved_in_bytes);
|
||||
}
|
||||
|
||||
void MetaspaceCounters::update_all() {
|
||||
if (UsePerfData) {
|
||||
update_used();
|
||||
update_capacity();
|
||||
update_max_capacity();
|
||||
}
|
||||
}
|
||||
|
||||
void MetaspaceCounters::initialize_performance_counters() {
|
||||
if (UsePerfData) {
|
||||
assert(_metaspace_counters == NULL, "Should only be initialized once");
|
||||
_metaspace_counters = new MetaspaceCounters();
|
||||
assert(_perf_counters == NULL, "Should only be initialized once");
|
||||
|
||||
size_t min_capacity = MetaspaceAux::min_chunk_size();
|
||||
size_t capacity = calculate_capacity();
|
||||
size_t max_capacity = MetaspaceAux::reserved_in_bytes();
|
||||
size_t used = MetaspaceAux::allocated_used_bytes();
|
||||
|
||||
_perf_counters = new MetaspacePerfCounters("metaspace", min_capacity, capacity, max_capacity, used);
|
||||
}
|
||||
}
|
||||
|
||||
void MetaspaceCounters::update_performance_counters() {
|
||||
if (UsePerfData) {
|
||||
assert(_metaspace_counters != NULL, "Should be initialized");
|
||||
_metaspace_counters->update_all();
|
||||
assert(_perf_counters != NULL, "Should be initialized");
|
||||
|
||||
size_t capacity = calculate_capacity();
|
||||
size_t max_capacity = MetaspaceAux::reserved_in_bytes();
|
||||
size_t used = MetaspaceAux::allocated_used_bytes();
|
||||
|
||||
_perf_counters->update(capacity, max_capacity, used);
|
||||
}
|
||||
}
|
||||
|
||||
MetaspacePerfCounters* CompressedClassSpaceCounters::_perf_counters = NULL;
|
||||
|
||||
size_t CompressedClassSpaceCounters::calculate_capacity() {
|
||||
return MetaspaceAux::allocated_capacity_bytes(_class_type) +
|
||||
MetaspaceAux::free_bytes(_class_type) +
|
||||
MetaspaceAux::free_chunks_total_in_bytes(_class_type);
|
||||
}
|
||||
|
||||
void CompressedClassSpaceCounters::update_performance_counters() {
|
||||
if (UsePerfData && UseCompressedKlassPointers) {
|
||||
assert(_perf_counters != NULL, "Should be initialized");
|
||||
|
||||
size_t capacity = calculate_capacity();
|
||||
size_t max_capacity = MetaspaceAux::reserved_in_bytes(_class_type);
|
||||
size_t used = MetaspaceAux::allocated_used_bytes(_class_type);
|
||||
|
||||
_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 (UseCompressedKlassPointers) {
|
||||
size_t min_capacity = MetaspaceAux::min_chunk_size();
|
||||
size_t capacity = calculate_capacity();
|
||||
size_t max_capacity = MetaspaceAux::reserved_in_bytes(_class_type);
|
||||
size_t used = MetaspaceAux::allocated_used_bytes(_class_type);
|
||||
|
||||
_perf_counters = new MetaspacePerfCounters(ns, min_capacity, capacity, max_capacity, used);
|
||||
} else {
|
||||
_perf_counters = new MetaspacePerfCounters(ns, 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,31 +25,27 @@
|
|||
#ifndef SHARE_VM_MEMORY_METASPACECOUNTERS_HPP
|
||||
#define SHARE_VM_MEMORY_METASPACECOUNTERS_HPP
|
||||
|
||||
#include "runtime/perfData.hpp"
|
||||
#include "memory/metaspace.hpp"
|
||||
|
||||
class MetaspacePerfCounters;
|
||||
|
||||
class MetaspaceCounters: public AllStatic {
|
||||
static MetaspacePerfCounters* _perf_counters;
|
||||
static size_t calculate_capacity();
|
||||
|
||||
class MetaspaceCounters: public CHeapObj<mtClass> {
|
||||
friend class VMStructs;
|
||||
PerfVariable* _capacity;
|
||||
PerfVariable* _used;
|
||||
PerfVariable* _max_capacity;
|
||||
static MetaspaceCounters* _metaspace_counters;
|
||||
void initialize(size_t min_capacity,
|
||||
size_t max_capacity,
|
||||
size_t curr_capacity,
|
||||
size_t used);
|
||||
size_t calc_total_capacity();
|
||||
public:
|
||||
MetaspaceCounters();
|
||||
~MetaspaceCounters();
|
||||
|
||||
void update_capacity();
|
||||
void update_used();
|
||||
void update_max_capacity();
|
||||
|
||||
void update_all();
|
||||
|
||||
static void initialize_performance_counters();
|
||||
static void update_performance_counters();
|
||||
|
||||
};
|
||||
|
||||
class CompressedClassSpaceCounters: public AllStatic {
|
||||
static MetaspacePerfCounters* _perf_counters;
|
||||
static size_t calculate_capacity();
|
||||
static const Metaspace::MetadataType _class_type = Metaspace::ClassType;
|
||||
|
||||
public:
|
||||
static void initialize_performance_counters();
|
||||
static void update_performance_counters();
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_MEMORY_METASPACECOUNTERS_HPP
|
||||
|
|
|
@ -1101,6 +1101,8 @@ bool universe_post_init() {
|
|||
|
||||
// Initialize performance counters for metaspaces
|
||||
MetaspaceCounters::initialize_performance_counters();
|
||||
CompressedClassSpaceCounters::initialize_performance_counters();
|
||||
|
||||
MemoryService::add_metaspace_memory_pools();
|
||||
|
||||
GC_locker::unlock(); // allow gc after bootstrapping
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue