< 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 >