< prev index next >
src/hotspot/share/memory/metaspace.cpp
Print this page
rev 49017 : [mq]: metaspace-stat
@@ -37,10 +37,11 @@
#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,10 +50,11 @@
#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,11 +151,11 @@
ChunkTreeDictionary* humongous_dictionary() {
return &_humongous_dictionary;
}
// Size, in metaspace words, of all chunks managed by this ChunkManager
- size_t _free_chunks_total;
+ 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,11 +176,10 @@
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];
@@ -191,11 +192,11 @@
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_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,20 +285,19 @@
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);
+ // 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);
- 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;
@@ -1846,34 +1846,34 @@
}
#endif
// ChunkManager methods
size_t ChunkManager::free_chunks_total_words() {
- return _free_chunks_total;
+ 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 += c->word_size();
+ _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 >= c->word_size(),
+ 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, c->word_size());
+ "(now: " SIZE_FORMAT ", decrement value: " SIZE_FORMAT ").", _free_chunks_total_words, c->word_size());
_free_chunks_count --;
- _free_chunks_total -= c->word_size();
+ _free_chunks_total_words -= c->word_size();
}
size_t ChunkManager::free_chunks_count() {
#ifdef ASSERT
if (!UseConcMarkSweepGC && !SpaceManager::expand_lock()->is_locked()) {
@@ -1909,38 +1909,24 @@
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,
+ assert(sum_free_chunks() == _free_chunks_total_words,
"_free_chunks_total " SIZE_FORMAT " is not the"
- " same as sum " SIZE_FORMAT, _free_chunks_total,
+ " same as sum " SIZE_FORMAT, _free_chunks_total_words,
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();
}
@@ -1948,22 +1934,10 @@
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];
@@ -2155,14 +2129,10 @@
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);
@@ -2212,29 +2182,42 @@
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");
+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);
+}
- // Note: keep lock protection only to retrieving statistics; keep printing
- // out of lock protection
+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->get_statistics(&stat);
- ChunkManager::print_statistics(&stat, out, scale);
+ 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->get_statistics(&stat);
- ChunkManager::print_statistics(&stat, out, scale);
+ class_cm->print_on(out, scale);
} else {
out->print_cr("unavailable.");
}
}
@@ -2397,12 +2380,11 @@
} else {
st->cr();
}
}
- chunk_manager()->locked_print_free_chunks(st);
- chunk_manager()->locked_print_sum_free_chunks(st);
+ 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,11 +3298,11 @@
reserved_bytes(Metaspace::ClassType) / scale, unit,
committed_bytes(Metaspace::ClassType) / scale, unit);
}
out->cr();
- ChunkManager::print_all_chunkmanagers(out, scale);
+ ChunkManager::print_all_chunkmanagers_on(out, scale);
out->cr();
out->print_cr("Per-classloader metadata:");
out->cr();
@@ -3998,11 +3980,11 @@
}
}
LogStream ls(log.info());
MetaspaceAux::dump(&ls);
MetaspaceAux::print_metaspace_map(&ls, mdtype);
- ChunkManager::print_all_chunkmanagers(&ls);
+ 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 >