Path: blob/master/src/hotspot/share/memory/metaspace/metaspaceStatistics.cpp
40957 views
/*1* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.2* Copyright (c) 2018, 2020 SAP SE. All rights reserved.3* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.4*5* This code is free software; you can redistribute it and/or modify it6* under the terms of the GNU General Public License version 2 only, as7* published by the Free Software Foundation.8*9* This code is distributed in the hope that it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* version 2 for more details (a copy is included in the LICENSE file that13* accompanied this code).14*15* You should have received a copy of the GNU General Public License version16* 2 along with this work; if not, write to the Free Software Foundation,17* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.18*19* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA20* or visit www.oracle.com if you need additional information or have any21* questions.22*23*/2425#include "precompiled.hpp"26#include "memory/metaspace/metaspaceCommon.hpp"27#include "memory/metaspace/metaspaceStatistics.hpp"28#include "utilities/debug.hpp"29#include "utilities/globalDefinitions.hpp"30#include "utilities/ostream.hpp"3132namespace metaspace {3334// Returns total word size of all chunks in this manager.35void ChunkManagerStats::add(const ChunkManagerStats& other) {36for (chunklevel_t l = chunklevel::LOWEST_CHUNK_LEVEL; l <= chunklevel::HIGHEST_CHUNK_LEVEL; l++) {37_num_chunks[l] += other._num_chunks[l];38_committed_word_size[l] += other._committed_word_size[l];39}40}4142// Returns total word size of all chunks in this manager.43size_t ChunkManagerStats::total_word_size() const {44size_t s = 0;45for (chunklevel_t l = chunklevel::LOWEST_CHUNK_LEVEL; l <= chunklevel::HIGHEST_CHUNK_LEVEL; l++) {46s += _num_chunks[l] * chunklevel::word_size_for_level(l);47}48return s;49}5051// Returns total committed word size of all chunks in this manager.52size_t ChunkManagerStats::total_committed_word_size() const {53size_t s = 0;54for (chunklevel_t l = chunklevel::LOWEST_CHUNK_LEVEL; l <= chunklevel::HIGHEST_CHUNK_LEVEL; l++) {55s += _committed_word_size[l];56}57return s;58}5960void ChunkManagerStats::print_on(outputStream* st, size_t scale) const {61// Note: used as part of MetaspaceReport so formatting matters.62size_t total_size = 0;63size_t total_committed_size = 0;64for (chunklevel_t l = chunklevel::LOWEST_CHUNK_LEVEL; l <= chunklevel::HIGHEST_CHUNK_LEVEL; l++) {65st->cr();66chunklevel::print_chunk_size(st, l);67st->print(": ");68if (_num_chunks[l] > 0) {69const size_t word_size = _num_chunks[l] * chunklevel::word_size_for_level(l);7071st->print("%4d, capacity=", _num_chunks[l]);72print_scaled_words(st, word_size, scale);7374st->print(", committed=");75print_scaled_words_and_percentage(st, _committed_word_size[l], word_size, scale);7677total_size += word_size;78total_committed_size += _committed_word_size[l];79} else {80st->print("(none)");81}82}83st->cr();84st->print("Total word size: ");85print_scaled_words(st, total_size, scale);86st->print(", committed: ");87print_scaled_words_and_percentage(st, total_committed_size, total_size, scale);88st->cr();89}9091#ifdef ASSERT92void ChunkManagerStats::verify() const {93assert(total_committed_word_size() <= total_word_size(),94"Sanity");95}96#endif9798void InUseChunkStats::print_on(outputStream* st, size_t scale) const {99int col = st->position();100st->print("%4d chunk%s, ", _num, _num != 1 ? "s" : "");101if (_num > 0) {102col += 14; st->fill_to(col);103104print_scaled_words(st, _word_size, scale, 5);105st->print(" capacity,");106107col += 20; st->fill_to(col);108print_scaled_words_and_percentage(st, _committed_words, _word_size, scale, 5);109st->print(" committed, ");110111col += 18; st->fill_to(col);112print_scaled_words_and_percentage(st, _used_words, _word_size, scale, 5);113st->print(" used, ");114115col += 20; st->fill_to(col);116print_scaled_words_and_percentage(st, _free_words, _word_size, scale, 5);117st->print(" free, ");118119col += 20; st->fill_to(col);120print_scaled_words_and_percentage(st, _waste_words, _word_size, scale, 5);121st->print(" waste ");122123}124}125126#ifdef ASSERT127void InUseChunkStats::verify() const {128assert(_word_size >= _committed_words &&129_committed_words == _used_words + _free_words + _waste_words,130"Sanity: cap " SIZE_FORMAT ", committed " SIZE_FORMAT ", used " SIZE_FORMAT ", free " SIZE_FORMAT ", waste " SIZE_FORMAT ".",131_word_size, _committed_words, _used_words, _free_words, _waste_words);132}133#endif134135void ArenaStats::add(const ArenaStats& other) {136for (chunklevel_t l = chunklevel::LOWEST_CHUNK_LEVEL; l <= chunklevel::HIGHEST_CHUNK_LEVEL; l++) {137_stats[l].add(other._stats[l]);138}139_free_blocks_num += other._free_blocks_num;140_free_blocks_word_size += other._free_blocks_word_size;141}142143// Returns total chunk statistics over all chunk types.144InUseChunkStats ArenaStats::totals() const {145InUseChunkStats out;146for (chunklevel_t l = chunklevel::LOWEST_CHUNK_LEVEL; l <= chunklevel::HIGHEST_CHUNK_LEVEL; l++) {147out.add(_stats[l]);148}149return out;150}151152void ArenaStats::print_on(outputStream* st, size_t scale, bool detailed) const {153streamIndentor sti(st);154if (detailed) {155st->cr_indent();156st->print("Usage by chunk level:");157{158streamIndentor sti2(st);159for (chunklevel_t l = chunklevel::LOWEST_CHUNK_LEVEL; l <= chunklevel::HIGHEST_CHUNK_LEVEL; l++) {160st->cr_indent();161chunklevel::print_chunk_size(st, l);162st->print(" chunks: ");163if (_stats[l]._num == 0) {164st->print(" (none)");165} else {166_stats[l].print_on(st, scale);167}168}169170st->cr_indent();171st->print("%15s: ", "-total-");172totals().print_on(st, scale);173}174if (_free_blocks_num > 0) {175st->cr_indent();176st->print("deallocated: " UINTX_FORMAT " blocks with ", _free_blocks_num);177print_scaled_words(st, _free_blocks_word_size, scale);178}179} else {180totals().print_on(st, scale);181st->print(", ");182st->print("deallocated: " UINTX_FORMAT " blocks with ", _free_blocks_num);183print_scaled_words(st, _free_blocks_word_size, scale);184}185}186187#ifdef ASSERT188189void ArenaStats::verify() const {190size_t total_used = 0;191for (chunklevel_t l = chunklevel::LOWEST_CHUNK_LEVEL; l <= chunklevel::HIGHEST_CHUNK_LEVEL; l++) {192_stats[l].verify();193total_used += _stats[l]._used_words;194}195// Deallocated allocations still count as used196assert(total_used >= _free_blocks_word_size,197"Sanity");198}199#endif200201// Returns total arena statistics for both class and non-class metaspace202ArenaStats ClmsStats::totals() const {203ArenaStats out;204out.add(_arena_stats_nonclass);205out.add(_arena_stats_class);206return out;207}208209void ClmsStats::print_on(outputStream* st, size_t scale, bool detailed) const {210streamIndentor sti(st);211st->cr_indent();212if (Metaspace::using_class_space()) {213st->print("Non-Class: ");214}215_arena_stats_nonclass.print_on(st, scale, detailed);216if (detailed) {217st->cr();218}219if (Metaspace::using_class_space()) {220st->cr_indent();221st->print(" Class: ");222_arena_stats_class.print_on(st, scale, detailed);223if (detailed) {224st->cr();225}226st->cr_indent();227st->print(" Both: ");228totals().print_on(st, scale, detailed);229if (detailed) {230st->cr();231}232}233st->cr();234}235236#ifdef ASSERT237void ClmsStats::verify() const {238_arena_stats_nonclass.verify();239_arena_stats_class.verify();240}241#endif242243} // end namespace metaspace244245246247