8014862: Add fast Metasapce capacity and used per MetadataType
Reviewed-by: ehelin, stefank
This commit is contained in:
parent
47c64fb0c3
commit
c7a9104bb7
@ -562,6 +562,9 @@ class SpaceManager : public CHeapObj<mtClass> {
|
||||
// protects allocations and contains.
|
||||
Mutex* const _lock;
|
||||
|
||||
// Type of metadata allocated.
|
||||
Metaspace::MetadataType _mdtype;
|
||||
|
||||
// Chunk related size
|
||||
size_t _medium_chunk_bunch;
|
||||
|
||||
@ -606,6 +609,7 @@ class SpaceManager : public CHeapObj<mtClass> {
|
||||
return (BlockFreelist*) &_block_freelists;
|
||||
}
|
||||
|
||||
Metaspace::MetadataType mdtype() { return _mdtype; }
|
||||
VirtualSpaceList* vs_list() const { return _vs_list; }
|
||||
|
||||
Metachunk* current_chunk() const { return _current_chunk; }
|
||||
@ -626,7 +630,8 @@ class SpaceManager : public CHeapObj<mtClass> {
|
||||
void initialize();
|
||||
|
||||
public:
|
||||
SpaceManager(Mutex* lock,
|
||||
SpaceManager(Metaspace::MetadataType mdtype,
|
||||
Mutex* lock,
|
||||
VirtualSpaceList* vs_list);
|
||||
~SpaceManager();
|
||||
|
||||
@ -2032,9 +2037,11 @@ void SpaceManager::print_on(outputStream* st) const {
|
||||
}
|
||||
}
|
||||
|
||||
SpaceManager::SpaceManager(Mutex* lock,
|
||||
SpaceManager::SpaceManager(Metaspace::MetadataType mdtype,
|
||||
Mutex* lock,
|
||||
VirtualSpaceList* vs_list) :
|
||||
_vs_list(vs_list),
|
||||
_mdtype(mdtype),
|
||||
_allocated_blocks_words(0),
|
||||
_allocated_chunks_words(0),
|
||||
_allocated_chunks_count(0),
|
||||
@ -2050,27 +2057,27 @@ void SpaceManager::inc_size_metrics(size_t words) {
|
||||
_allocated_chunks_words = _allocated_chunks_words + words;
|
||||
_allocated_chunks_count++;
|
||||
// Global total of capacity in allocated Metachunks
|
||||
MetaspaceAux::inc_capacity(words);
|
||||
MetaspaceAux::inc_capacity(mdtype(), words);
|
||||
// Global total of allocated Metablocks.
|
||||
// used_words_slow() includes the overhead in each
|
||||
// Metachunk so include it in the used when the
|
||||
// Metachunk is first added (so only added once per
|
||||
// Metachunk).
|
||||
MetaspaceAux::inc_used(Metachunk::overhead());
|
||||
MetaspaceAux::inc_used(mdtype(), Metachunk::overhead());
|
||||
}
|
||||
|
||||
void SpaceManager::inc_used_metrics(size_t words) {
|
||||
// Add to the per SpaceManager total
|
||||
Atomic::add_ptr(words, &_allocated_blocks_words);
|
||||
// Add to the global total
|
||||
MetaspaceAux::inc_used(words);
|
||||
MetaspaceAux::inc_used(mdtype(), words);
|
||||
}
|
||||
|
||||
void SpaceManager::dec_total_from_size_metrics() {
|
||||
MetaspaceAux::dec_capacity(allocated_chunks_words());
|
||||
MetaspaceAux::dec_used(allocated_blocks_words());
|
||||
MetaspaceAux::dec_capacity(mdtype(), allocated_chunks_words());
|
||||
MetaspaceAux::dec_used(mdtype(), allocated_blocks_words());
|
||||
// Also deduct the overhead per Metachunk
|
||||
MetaspaceAux::dec_used(allocated_chunks_count() * Metachunk::overhead());
|
||||
MetaspaceAux::dec_used(mdtype(), allocated_chunks_count() * Metachunk::overhead());
|
||||
}
|
||||
|
||||
void SpaceManager::initialize() {
|
||||
@ -2470,8 +2477,8 @@ void SpaceManager::mangle_freed_chunks() {
|
||||
// MetaspaceAux
|
||||
|
||||
|
||||
size_t MetaspaceAux::_allocated_capacity_words = 0;
|
||||
size_t MetaspaceAux::_allocated_used_words = 0;
|
||||
size_t MetaspaceAux::_allocated_capacity_words[] = {0, 0};
|
||||
size_t MetaspaceAux::_allocated_used_words[] = {0, 0};
|
||||
|
||||
size_t MetaspaceAux::free_bytes() {
|
||||
size_t result = 0;
|
||||
@ -2484,40 +2491,40 @@ size_t MetaspaceAux::free_bytes() {
|
||||
return result;
|
||||
}
|
||||
|
||||
void MetaspaceAux::dec_capacity(size_t words) {
|
||||
void MetaspaceAux::dec_capacity(Metaspace::MetadataType mdtype, size_t words) {
|
||||
assert_lock_strong(SpaceManager::expand_lock());
|
||||
assert(words <= _allocated_capacity_words,
|
||||
assert(words <= allocated_capacity_words(mdtype),
|
||||
err_msg("About to decrement below 0: words " SIZE_FORMAT
|
||||
" is greater than _allocated_capacity_words " SIZE_FORMAT,
|
||||
words, _allocated_capacity_words));
|
||||
_allocated_capacity_words = _allocated_capacity_words - words;
|
||||
" is greater than _allocated_capacity_words[%u] " SIZE_FORMAT,
|
||||
words, mdtype, allocated_capacity_words(mdtype)));
|
||||
_allocated_capacity_words[mdtype] -= words;
|
||||
}
|
||||
|
||||
void MetaspaceAux::inc_capacity(size_t words) {
|
||||
void MetaspaceAux::inc_capacity(Metaspace::MetadataType mdtype, size_t words) {
|
||||
assert_lock_strong(SpaceManager::expand_lock());
|
||||
// Needs to be atomic
|
||||
_allocated_capacity_words = _allocated_capacity_words + words;
|
||||
_allocated_capacity_words[mdtype] += words;
|
||||
}
|
||||
|
||||
void MetaspaceAux::dec_used(size_t words) {
|
||||
assert(words <= _allocated_used_words,
|
||||
void MetaspaceAux::dec_used(Metaspace::MetadataType mdtype, size_t words) {
|
||||
assert(words <= allocated_used_words(mdtype),
|
||||
err_msg("About to decrement below 0: words " SIZE_FORMAT
|
||||
" is greater than _allocated_used_words " SIZE_FORMAT,
|
||||
words, _allocated_used_words));
|
||||
" is greater than _allocated_used_words[%u] " SIZE_FORMAT,
|
||||
words, mdtype, allocated_used_words(mdtype)));
|
||||
// For CMS deallocation of the Metaspaces occurs during the
|
||||
// sweep which is a concurrent phase. Protection by the expand_lock()
|
||||
// is not enough since allocation is on a per Metaspace basis
|
||||
// and protected by the Metaspace lock.
|
||||
jlong minus_words = (jlong) - (jlong) words;
|
||||
Atomic::add_ptr(minus_words, &_allocated_used_words);
|
||||
Atomic::add_ptr(minus_words, &_allocated_used_words[mdtype]);
|
||||
}
|
||||
|
||||
void MetaspaceAux::inc_used(size_t words) {
|
||||
void MetaspaceAux::inc_used(Metaspace::MetadataType mdtype, size_t words) {
|
||||
// _allocated_used_words tracks allocations for
|
||||
// each piece of metadata. Those allocations are
|
||||
// generally done concurrently by different application
|
||||
// threads so must be done atomically.
|
||||
Atomic::add_ptr(words, &_allocated_used_words);
|
||||
Atomic::add_ptr(words, &_allocated_used_words[mdtype]);
|
||||
}
|
||||
|
||||
size_t MetaspaceAux::used_bytes_slow(Metaspace::MetadataType mdtype) {
|
||||
@ -2619,21 +2626,19 @@ void MetaspaceAux::print_on(outputStream* out) {
|
||||
SIZE_FORMAT "K, used " SIZE_FORMAT "K,"
|
||||
" reserved " SIZE_FORMAT "K",
|
||||
allocated_capacity_bytes()/K, allocated_used_bytes()/K, reserved_in_bytes()/K);
|
||||
#if 0
|
||||
// The calls to capacity_bytes_slow() and used_bytes_slow() cause
|
||||
// lock ordering assertion failures with some collectors. Do
|
||||
// not include this code until the lock ordering is fixed.
|
||||
if (PrintGCDetails && Verbose) {
|
||||
|
||||
out->print_cr(" data space "
|
||||
SIZE_FORMAT "K, used " SIZE_FORMAT "K,"
|
||||
" reserved " SIZE_FORMAT "K",
|
||||
capacity_bytes_slow(nct)/K, used_bytes_slow(nct)/K, reserved_in_bytes(nct)/K);
|
||||
allocated_capacity_bytes(nct)/K,
|
||||
allocated_used_bytes(nct)/K,
|
||||
reserved_in_bytes(nct)/K);
|
||||
out->print_cr(" class space "
|
||||
SIZE_FORMAT "K, used " SIZE_FORMAT "K,"
|
||||
" reserved " SIZE_FORMAT "K",
|
||||
capacity_bytes_slow(ct)/K, used_bytes_slow(ct)/K, reserved_in_bytes(ct)/K);
|
||||
}
|
||||
#endif
|
||||
allocated_capacity_bytes(ct)/K,
|
||||
allocated_used_bytes(ct)/K,
|
||||
reserved_in_bytes(ct)/K);
|
||||
}
|
||||
|
||||
// Print information for class space and data space separately.
|
||||
@ -2717,24 +2722,42 @@ void MetaspaceAux::verify_free_chunks() {
|
||||
void MetaspaceAux::verify_capacity() {
|
||||
#ifdef ASSERT
|
||||
size_t running_sum_capacity_bytes = allocated_capacity_bytes();
|
||||
// For purposes of the running sum of used, verify against capacity
|
||||
// For purposes of the running sum of capacity, verify against capacity
|
||||
size_t capacity_in_use_bytes = capacity_bytes_slow();
|
||||
assert(running_sum_capacity_bytes == capacity_in_use_bytes,
|
||||
err_msg("allocated_capacity_words() * BytesPerWord " SIZE_FORMAT
|
||||
" capacity_bytes_slow()" SIZE_FORMAT,
|
||||
running_sum_capacity_bytes, capacity_in_use_bytes));
|
||||
for (Metaspace::MetadataType i = Metaspace::ClassType;
|
||||
i < Metaspace:: MetadataTypeCount;
|
||||
i = (Metaspace::MetadataType)(i + 1)) {
|
||||
size_t capacity_in_use_bytes = capacity_bytes_slow(i);
|
||||
assert(allocated_capacity_bytes(i) == capacity_in_use_bytes,
|
||||
err_msg("allocated_capacity_bytes(%u) " SIZE_FORMAT
|
||||
" capacity_bytes_slow(%u)" SIZE_FORMAT,
|
||||
i, allocated_capacity_bytes(i), i, capacity_in_use_bytes));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void MetaspaceAux::verify_used() {
|
||||
#ifdef ASSERT
|
||||
size_t running_sum_used_bytes = allocated_used_bytes();
|
||||
// For purposes of the running sum of used, verify against capacity
|
||||
// For purposes of the running sum of used, verify against used
|
||||
size_t used_in_use_bytes = used_bytes_slow();
|
||||
assert(allocated_used_bytes() == used_in_use_bytes,
|
||||
err_msg("allocated_used_bytes() " SIZE_FORMAT
|
||||
" used_bytes_slow()()" SIZE_FORMAT,
|
||||
" used_bytes_slow()" SIZE_FORMAT,
|
||||
allocated_used_bytes(), used_in_use_bytes));
|
||||
for (Metaspace::MetadataType i = Metaspace::ClassType;
|
||||
i < Metaspace:: MetadataTypeCount;
|
||||
i = (Metaspace::MetadataType)(i + 1)) {
|
||||
size_t used_in_use_bytes = used_bytes_slow(i);
|
||||
assert(allocated_used_bytes(i) == used_in_use_bytes,
|
||||
err_msg("allocated_used_bytes(%u) " SIZE_FORMAT
|
||||
" used_bytes_slow(%u)" SIZE_FORMAT,
|
||||
i, allocated_used_bytes(i), i, used_in_use_bytes));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -2835,7 +2858,7 @@ void Metaspace::initialize(Mutex* lock,
|
||||
assert(space_list() != NULL,
|
||||
"Metadata VirtualSpaceList has not been initialized");
|
||||
|
||||
_vsm = new SpaceManager(lock, space_list());
|
||||
_vsm = new SpaceManager(Metaspace::NonClassType, lock, space_list());
|
||||
if (_vsm == NULL) {
|
||||
return;
|
||||
}
|
||||
@ -2849,7 +2872,7 @@ void Metaspace::initialize(Mutex* lock,
|
||||
"Class VirtualSpaceList has not been initialized");
|
||||
|
||||
// Allocate SpaceManager for classes.
|
||||
_class_vsm = new SpaceManager(lock, class_space_list());
|
||||
_class_vsm = new SpaceManager(Metaspace::ClassType, lock, class_space_list());
|
||||
if (_class_vsm == NULL) {
|
||||
return;
|
||||
}
|
||||
|
@ -86,7 +86,10 @@ class Metaspace : public CHeapObj<mtClass> {
|
||||
friend class MetaspaceAux;
|
||||
|
||||
public:
|
||||
enum MetadataType {ClassType, NonClassType};
|
||||
enum MetadataType {ClassType = 0,
|
||||
NonClassType = ClassType + 1,
|
||||
MetadataTypeCount = ClassType + 2
|
||||
};
|
||||
enum MetaspaceType {
|
||||
StandardMetaspaceType,
|
||||
BootMetaspaceType,
|
||||
@ -184,20 +187,22 @@ class MetaspaceAux : AllStatic {
|
||||
public:
|
||||
// Running sum of space in all Metachunks that has been
|
||||
// allocated to a Metaspace. This is used instead of
|
||||
// iterating over all the classloaders
|
||||
static size_t _allocated_capacity_words;
|
||||
// iterating over all the classloaders. One for each
|
||||
// type of Metadata
|
||||
static size_t _allocated_capacity_words[Metaspace:: MetadataTypeCount];
|
||||
// Running sum of space in all Metachunks that have
|
||||
// are being used for metadata.
|
||||
static size_t _allocated_used_words;
|
||||
// are being used for metadata. One for each
|
||||
// type of Metadata.
|
||||
static size_t _allocated_used_words[Metaspace:: MetadataTypeCount];
|
||||
|
||||
public:
|
||||
// Decrement and increment _allocated_capacity_words
|
||||
static void dec_capacity(size_t words);
|
||||
static void inc_capacity(size_t words);
|
||||
static void dec_capacity(Metaspace::MetadataType type, size_t words);
|
||||
static void inc_capacity(Metaspace::MetadataType type, size_t words);
|
||||
|
||||
// Decrement and increment _allocated_used_words
|
||||
static void dec_used(size_t words);
|
||||
static void inc_used(size_t words);
|
||||
static void dec_used(Metaspace::MetadataType type, size_t words);
|
||||
static void inc_used(Metaspace::MetadataType type, size_t words);
|
||||
|
||||
// Total of space allocated to metadata in all Metaspaces.
|
||||
// This sums the space used in each Metachunk by
|
||||
@ -211,18 +216,32 @@ class MetaspaceAux : AllStatic {
|
||||
static size_t free_chunks_total();
|
||||
static size_t free_chunks_total_in_bytes();
|
||||
|
||||
static size_t allocated_capacity_words(Metaspace::MetadataType mdtype) {
|
||||
return _allocated_capacity_words[mdtype];
|
||||
}
|
||||
static size_t allocated_capacity_words() {
|
||||
return _allocated_capacity_words;
|
||||
return _allocated_capacity_words[Metaspace::ClassType] +
|
||||
_allocated_capacity_words[Metaspace::NonClassType];
|
||||
}
|
||||
static size_t allocated_capacity_bytes(Metaspace::MetadataType mdtype) {
|
||||
return allocated_capacity_words(mdtype) * BytesPerWord;
|
||||
}
|
||||
static size_t allocated_capacity_bytes() {
|
||||
return _allocated_capacity_words * BytesPerWord;
|
||||
return allocated_capacity_words() * BytesPerWord;
|
||||
}
|
||||
|
||||
static size_t allocated_used_words(Metaspace::MetadataType mdtype) {
|
||||
return _allocated_used_words[mdtype];
|
||||
}
|
||||
static size_t allocated_used_words() {
|
||||
return _allocated_used_words;
|
||||
return _allocated_used_words[Metaspace::ClassType] +
|
||||
_allocated_used_words[Metaspace::NonClassType];
|
||||
}
|
||||
static size_t allocated_used_bytes(Metaspace::MetadataType mdtype) {
|
||||
return allocated_used_words(mdtype) * BytesPerWord;
|
||||
}
|
||||
static size_t allocated_used_bytes() {
|
||||
return _allocated_used_words * BytesPerWord;
|
||||
return allocated_used_words() * BytesPerWord;
|
||||
}
|
||||
|
||||
static size_t free_bytes();
|
||||
|
Loading…
Reference in New Issue
Block a user