提交 8def3880 编写于 作者: J jmasa

8014862: Add fast Metasapce capacity and used per MetadataType

Reviewed-by: ehelin, stefank
上级 cd76209f
......@@ -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);
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
out->print_cr(" data space "
SIZE_FORMAT "K, used " SIZE_FORMAT "K,"
" reserved " SIZE_FORMAT "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",
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();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册