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