< prev index next >
src/hotspot/share/memory/metaspace.cpp
Print this page
rev 49017 : [mq]: metaspace-stat
*** 37,46 ****
--- 37,47 ----
#include "memory/metaspaceGCThresholdUpdater.hpp"
#include "memory/metaspaceShared.hpp"
#include "memory/metaspaceTracer.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
+ #include "memory/virtualspace.hpp"
#include "runtime/atomic.hpp"
#include "runtime/globals.hpp"
#include "runtime/init.hpp"
#include "runtime/java.hpp"
#include "runtime/mutex.hpp"
*** 49,58 ****
--- 50,60 ----
#include "services/memoryService.hpp"
#include "utilities/align.hpp"
#include "utilities/copy.hpp"
#include "utilities/debug.hpp"
#include "utilities/macros.hpp"
+ #include "utilities/ostream.hpp"
typedef BinaryTreeDictionary<Metablock, FreeList<Metablock> > BlockTreeDictionary;
typedef BinaryTreeDictionary<Metachunk, FreeList<Metachunk> > ChunkTreeDictionary;
// Set this constant to enable slow integrity checking of the free chunk lists
*** 149,159 ****
ChunkTreeDictionary* humongous_dictionary() {
return &_humongous_dictionary;
}
// Size, in metaspace words, of all chunks managed by this ChunkManager
! size_t _free_chunks_total;
// Number of chunks in this ChunkManager
size_t _free_chunks_count;
// Update counters after a chunk was added or removed removed.
void account_for_added_chunk(const Metachunk* c);
--- 151,161 ----
ChunkTreeDictionary* humongous_dictionary() {
return &_humongous_dictionary;
}
// Size, in metaspace words, of all chunks managed by this ChunkManager
! size_t _free_chunks_total_words;
// Number of chunks in this ChunkManager
size_t _free_chunks_count;
// Update counters after a chunk was added or removed removed.
void account_for_added_chunk(const Metachunk* c);
*** 174,184 ****
void slow_locked_verify_free_chunks_count() {
if (metaspace_slow_verify) {
locked_verify_free_chunks_count();
}
}
- void verify_free_chunks_count();
struct ChunkManagerStatistics {
size_t num_by_type[NumberOfFreeLists];
size_t single_size_by_type[NumberOfFreeLists];
size_t total_size_by_type[NumberOfFreeLists];
--- 176,185 ----
*** 191,201 ****
static void print_statistics(const ChunkManagerStatistics* stat, outputStream* out, size_t scale);
public:
ChunkManager(size_t specialized_size, size_t small_size, size_t medium_size)
! : _free_chunks_total(0), _free_chunks_count(0) {
_free_chunks[SpecializedIndex].set_size(specialized_size);
_free_chunks[SmallIndex].set_size(small_size);
_free_chunks[MediumIndex].set_size(medium_size);
}
--- 192,202 ----
static void print_statistics(const ChunkManagerStatistics* stat, outputStream* out, size_t scale);
public:
ChunkManager(size_t specialized_size, size_t small_size, size_t medium_size)
! : _free_chunks_total_words(0), _free_chunks_count(0) {
_free_chunks[SpecializedIndex].set_size(specialized_size);
_free_chunks[SmallIndex].set_size(small_size);
_free_chunks[MediumIndex].set_size(medium_size);
}
*** 284,303 ****
void slow_locked_verify() {
if (metaspace_slow_verify) {
locked_verify();
}
}
- void verify_free_chunks_total();
! void locked_print_free_chunks(outputStream* st);
! void locked_print_sum_free_chunks(outputStream* st);
- void print_on(outputStream* st) const;
-
- // Prints composition for both non-class and (if available)
- // class chunk manager.
- static void print_all_chunkmanagers(outputStream* out, size_t scale = 1);
};
class SmallBlocks : public CHeapObj<mtClass> {
const static uint _small_block_max_size = sizeof(TreeChunk<Metablock, FreeList<Metablock> >)/HeapWordSize;
const static uint _small_block_min_size = sizeof(Metablock)/HeapWordSize;
--- 285,303 ----
void slow_locked_verify() {
if (metaspace_slow_verify) {
locked_verify();
}
}
! // Prints composition (number and total size of chunks per chunk size).
! void locked_print_on(outputStream* out, size_t scale = 1) const;
! void print_on(outputStream* out, size_t scale = 1) const;
!
! // Prints composition (number and total size of chunks per chunk size) for all
! // (class and non-class) chunk managers.
! static void print_all_chunkmanagers_on(outputStream* out, size_t scale = 1);
};
class SmallBlocks : public CHeapObj<mtClass> {
const static uint _small_block_max_size = sizeof(TreeChunk<Metablock, FreeList<Metablock> >)/HeapWordSize;
const static uint _small_block_min_size = sizeof(Metablock)/HeapWordSize;
*** 1846,1879 ****
}
#endif
// ChunkManager methods
size_t ChunkManager::free_chunks_total_words() {
! return _free_chunks_total;
}
size_t ChunkManager::free_chunks_total_bytes() {
return free_chunks_total_words() * BytesPerWord;
}
// Update internal accounting after a chunk was added
void ChunkManager::account_for_added_chunk(const Metachunk* c) {
assert_lock_strong(SpaceManager::expand_lock());
_free_chunks_count ++;
! _free_chunks_total += c->word_size();
}
// Update internal accounting after a chunk was removed
void ChunkManager::account_for_removed_chunk(const Metachunk* c) {
assert_lock_strong(SpaceManager::expand_lock());
assert(_free_chunks_count >= 1,
"ChunkManager::_free_chunks_count: about to go negative (" SIZE_FORMAT ").", _free_chunks_count);
! assert(_free_chunks_total >= c->word_size(),
"ChunkManager::_free_chunks_total: about to go negative"
! "(now: " SIZE_FORMAT ", decrement value: " SIZE_FORMAT ").", _free_chunks_total, c->word_size());
_free_chunks_count --;
! _free_chunks_total -= c->word_size();
}
size_t ChunkManager::free_chunks_count() {
#ifdef ASSERT
if (!UseConcMarkSweepGC && !SpaceManager::expand_lock()->is_locked()) {
--- 1846,1879 ----
}
#endif
// ChunkManager methods
size_t ChunkManager::free_chunks_total_words() {
! return _free_chunks_total_words;
}
size_t ChunkManager::free_chunks_total_bytes() {
return free_chunks_total_words() * BytesPerWord;
}
// Update internal accounting after a chunk was added
void ChunkManager::account_for_added_chunk(const Metachunk* c) {
assert_lock_strong(SpaceManager::expand_lock());
_free_chunks_count ++;
! _free_chunks_total_words += c->word_size();
}
// Update internal accounting after a chunk was removed
void ChunkManager::account_for_removed_chunk(const Metachunk* c) {
assert_lock_strong(SpaceManager::expand_lock());
assert(_free_chunks_count >= 1,
"ChunkManager::_free_chunks_count: about to go negative (" SIZE_FORMAT ").", _free_chunks_count);
! assert(_free_chunks_total_words >= c->word_size(),
"ChunkManager::_free_chunks_total: about to go negative"
! "(now: " SIZE_FORMAT ", decrement value: " SIZE_FORMAT ").", _free_chunks_total_words, c->word_size());
_free_chunks_count --;
! _free_chunks_total_words -= c->word_size();
}
size_t ChunkManager::free_chunks_count() {
#ifdef ASSERT
if (!UseConcMarkSweepGC && !SpaceManager::expand_lock()->is_locked()) {
*** 1909,1946 ****
return _free_chunks[index].size();
}
void ChunkManager::locked_verify_free_chunks_total() {
assert_lock_strong(SpaceManager::expand_lock());
! assert(sum_free_chunks() == _free_chunks_total,
"_free_chunks_total " SIZE_FORMAT " is not the"
! " same as sum " SIZE_FORMAT, _free_chunks_total,
sum_free_chunks());
}
- void ChunkManager::verify_free_chunks_total() {
- MutexLockerEx cl(SpaceManager::expand_lock(),
- Mutex::_no_safepoint_check_flag);
- locked_verify_free_chunks_total();
- }
-
void ChunkManager::locked_verify_free_chunks_count() {
assert_lock_strong(SpaceManager::expand_lock());
assert(sum_free_chunks_count() == _free_chunks_count,
"_free_chunks_count " SIZE_FORMAT " is not the"
" same as sum " SIZE_FORMAT, _free_chunks_count,
sum_free_chunks_count());
}
- void ChunkManager::verify_free_chunks_count() {
- #ifdef ASSERT
- MutexLockerEx cl(SpaceManager::expand_lock(),
- Mutex::_no_safepoint_check_flag);
- locked_verify_free_chunks_count();
- #endif
- }
-
void ChunkManager::verify() {
MutexLockerEx cl(SpaceManager::expand_lock(),
Mutex::_no_safepoint_check_flag);
locked_verify();
}
--- 1909,1932 ----
return _free_chunks[index].size();
}
void ChunkManager::locked_verify_free_chunks_total() {
assert_lock_strong(SpaceManager::expand_lock());
! assert(sum_free_chunks() == _free_chunks_total_words,
"_free_chunks_total " SIZE_FORMAT " is not the"
! " same as sum " SIZE_FORMAT, _free_chunks_total_words,
sum_free_chunks());
}
void ChunkManager::locked_verify_free_chunks_count() {
assert_lock_strong(SpaceManager::expand_lock());
assert(sum_free_chunks_count() == _free_chunks_count,
"_free_chunks_count " SIZE_FORMAT " is not the"
" same as sum " SIZE_FORMAT, _free_chunks_count,
sum_free_chunks_count());
}
void ChunkManager::verify() {
MutexLockerEx cl(SpaceManager::expand_lock(),
Mutex::_no_safepoint_check_flag);
locked_verify();
}
*** 1948,1969 ****
void ChunkManager::locked_verify() {
locked_verify_free_chunks_count();
locked_verify_free_chunks_total();
}
- void ChunkManager::locked_print_free_chunks(outputStream* st) {
- assert_lock_strong(SpaceManager::expand_lock());
- st->print_cr("Free chunk total " SIZE_FORMAT " count " SIZE_FORMAT,
- _free_chunks_total, _free_chunks_count);
- }
-
- void ChunkManager::locked_print_sum_free_chunks(outputStream* st) {
- assert_lock_strong(SpaceManager::expand_lock());
- st->print_cr("Sum free chunk total " SIZE_FORMAT " count " SIZE_FORMAT,
- sum_free_chunks(), sum_free_chunks_count());
- }
-
ChunkList* ChunkManager::free_chunks(ChunkIndex index) {
assert(index == SpecializedIndex || index == SmallIndex || index == MediumIndex,
"Bad index: %d", (int)index);
return &_free_chunks[index];
--- 1934,1943 ----
*** 2155,2168 ****
log.print("updated dictionary count " SIZE_FORMAT ".", _humongous_dictionary.total_count());
}
}
}
- void ChunkManager::print_on(outputStream* out) const {
- _humongous_dictionary.report_statistics(out);
- }
-
void ChunkManager::locked_get_statistics(ChunkManagerStatistics* stat) const {
assert_lock_strong(SpaceManager::expand_lock());
for (ChunkIndex i = ZeroIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) {
stat->num_by_type[i] = num_free_chunks(i);
stat->single_size_by_type[i] = size_by_index(i);
--- 2129,2138 ----
*** 2212,2240 ****
out->print_cr(" total size: %.2f%s.", (float)total / scale, unit);
}
}
! void ChunkManager::print_all_chunkmanagers(outputStream* out, size_t scale) {
! assert(scale == 1 || scale == K || scale == M || scale == G, "Invalid scale");
! // Note: keep lock protection only to retrieving statistics; keep printing
! // out of lock protection
ChunkManagerStatistics stat;
out->print_cr("Chunkmanager (non-class):");
const ChunkManager* const non_class_cm = Metaspace::chunk_manager_metadata();
if (non_class_cm != NULL) {
! non_class_cm->get_statistics(&stat);
! ChunkManager::print_statistics(&stat, out, scale);
} else {
out->print_cr("unavailable.");
}
out->print_cr("Chunkmanager (class):");
const ChunkManager* const class_cm = Metaspace::chunk_manager_class();
if (class_cm != NULL) {
! class_cm->get_statistics(&stat);
! ChunkManager::print_statistics(&stat, out, scale);
} else {
out->print_cr("unavailable.");
}
}
--- 2182,2223 ----
out->print_cr(" total size: %.2f%s.", (float)total / scale, unit);
}
}
! void ChunkManager::locked_print_on(outputStream* out, size_t scale = 1) const {
! assert_lock_strong(SpaceManager::expand_lock());
! ChunkManagerStatistics stat;
! locked_get_statistics(&stat);
! print_statistics(&stat, out, scale);
! }
! void ChunkManager::print_on(outputStream* out, size_t scale = 1) const {
ChunkManagerStatistics stat;
+ {
+ // Print out of lock protection
+ MutexLockerEx cl(SpaceManager::expand_lock(),
+ Mutex::_no_safepoint_check_flag);
+ locked_get_statistics(&stat);
+ }
+ print_statistics(&stat, out, scale);
+ }
+
+ void ChunkManager::print_all_chunkmanagers_on(outputStream* out, size_t scale) {
+ assert(scale == 1 || scale == K || scale == M || scale == G, "Invalid scale");
+
out->print_cr("Chunkmanager (non-class):");
const ChunkManager* const non_class_cm = Metaspace::chunk_manager_metadata();
if (non_class_cm != NULL) {
! non_class_cm->print_on(out, scale);
} else {
out->print_cr("unavailable.");
}
out->print_cr("Chunkmanager (class):");
const ChunkManager* const class_cm = Metaspace::chunk_manager_class();
if (class_cm != NULL) {
! class_cm->print_on(out, scale);
} else {
out->print_cr("unavailable.");
}
}
*** 2397,2408 ****
} else {
st->cr();
}
}
! chunk_manager()->locked_print_free_chunks(st);
! chunk_manager()->locked_print_sum_free_chunks(st);
}
size_t SpaceManager::calc_chunk_size(size_t word_size) {
// Decide between a small chunk and a medium chunk. Up to
--- 2380,2390 ----
} else {
st->cr();
}
}
! chunk_manager()->print_on(st, 1024);
}
size_t SpaceManager::calc_chunk_size(size_t word_size) {
// Decide between a small chunk and a medium chunk. Up to
*** 3316,3326 ****
reserved_bytes(Metaspace::ClassType) / scale, unit,
committed_bytes(Metaspace::ClassType) / scale, unit);
}
out->cr();
! ChunkManager::print_all_chunkmanagers(out, scale);
out->cr();
out->print_cr("Per-classloader metadata:");
out->cr();
--- 3298,3308 ----
reserved_bytes(Metaspace::ClassType) / scale, unit,
committed_bytes(Metaspace::ClassType) / scale, unit);
}
out->cr();
! ChunkManager::print_all_chunkmanagers_on(out, scale);
out->cr();
out->print_cr("Per-classloader metadata:");
out->cr();
*** 3998,4008 ****
}
}
LogStream ls(log.info());
MetaspaceAux::dump(&ls);
MetaspaceAux::print_metaspace_map(&ls, mdtype);
! ChunkManager::print_all_chunkmanagers(&ls);
}
bool out_of_compressed_class_space = false;
if (is_class_space_allocation(mdtype)) {
Metaspace* metaspace = loader_data->metaspace_non_null();
--- 3980,3990 ----
}
}
LogStream ls(log.info());
MetaspaceAux::dump(&ls);
MetaspaceAux::print_metaspace_map(&ls, mdtype);
! ChunkManager::print_all_chunkmanagers_on(&ls);
}
bool out_of_compressed_class_space = false;
if (is_class_space_allocation(mdtype)) {
Metaspace* metaspace = loader_data->metaspace_non_null();
< prev index next >