--- /dev/null 2018-04-24 09:11:08.850175259 +0200 +++ new/src/hotspot/share/memory/metaspace/metaspaceStatistics.cpp 2018-04-24 07:16:46.577262390 +0200 @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, SAP and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +#include "precompiled.hpp" + +#include "memory/metachunk.hpp" +#include "memory/metaspace/metaspaceCommon.hpp" +#include "memory/metaspace/metaspaceStatistics.hpp" +#include "utilities/debug.hpp" +#include "utilities/globalDefinitions.hpp" +#include "utilities/ostream.hpp" + +namespace metaspace { +namespace internals { + +// FreeChunksStatistics methods + +FreeChunksStatistics::FreeChunksStatistics() +: _num(0), _cap(0) +{} + +void FreeChunksStatistics::reset() { + _num = 0; _cap = 0; +} + +void FreeChunksStatistics::add(uintx n, size_t s) { + _num += n; _cap += s; +} + +void FreeChunksStatistics::add(const FreeChunksStatistics& other) { + _num += other._num; + _cap += other._cap; +} + +void FreeChunksStatistics::print_on(outputStream* st, size_t scale) const { + st->print(UINTX_FORMAT, _num); + st->print(" chunks, total capacity "); + print_scaled_words(st, _cap, scale); +} + +// ChunkManagerStatistics methods + +void ChunkManagerStatistics::reset() { + for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { + _chunk_stats[i].reset(); + } +} + +size_t ChunkManagerStatistics::total_capacity() const { + return _chunk_stats[SpecializedIndex].cap() + + _chunk_stats[SmallIndex].cap() + + _chunk_stats[MediumIndex].cap() + + _chunk_stats[HumongousIndex].cap(); +} + +void ChunkManagerStatistics::print_on(outputStream* st, size_t scale) const { + FreeChunksStatistics totals; + for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { + st->cr(); + st->print("%12s chunks: ", chunk_size_name(i)); + if (_chunk_stats[i].num() > 0) { + st->print(UINTX_FORMAT_W(4) ", capacity ", _chunk_stats[i].num()); + print_scaled_words(st, _chunk_stats[i].cap(), scale); + } else { + st->print("(none)"); + } + totals.add(_chunk_stats[i]); + } + st->cr(); + st->print("%19s: " UINTX_FORMAT_W(4) ", capacity=", "Total", totals.num()); + print_scaled_words(st, totals.cap(), scale); + st->cr(); +} + +// UsedChunksStatistics methods + +UsedChunksStatistics::UsedChunksStatistics() +: _num(0), _cap(0), _used(0), _free(0), _waste(0), _overhead(0) +{} + +void UsedChunksStatistics::reset() { + _num = 0; + _cap = _overhead = _used = _free = _waste = 0; +} + +void UsedChunksStatistics::add(const UsedChunksStatistics& other) { + _num += other._num; + _cap += other._cap; + _used += other._used; + _free += other._free; + _waste += other._waste; + _overhead += other._overhead; + DEBUG_ONLY(check_sanity()); +} + +void UsedChunksStatistics::print_on(outputStream* st, size_t scale) const { + int col = st->position(); + st->print(UINTX_FORMAT_W(4) " chunk%s, ", _num, _num != 1 ? "s" : ""); + if (_num > 0) { + col += 14; st->fill_to(col); + + print_scaled_words(st, _cap, scale, 5); + st->print(" capacity, "); + + col += 18; st->fill_to(col); + print_scaled_words_and_percentage(st, _used, _cap, scale, 5); + st->print(" used, "); + + col += 20; st->fill_to(col); + print_scaled_words_and_percentage(st, _free, _cap, scale, 5); + st->print(" free, "); + + col += 20; st->fill_to(col); + print_scaled_words_and_percentage(st, _waste, _cap, scale, 5); + st->print(" waste, "); + + col += 20; st->fill_to(col); + print_scaled_words_and_percentage(st, _overhead, _cap, scale, 5); + st->print(" overhead"); + } + DEBUG_ONLY(check_sanity()); +} + +#ifdef ASSERT +void UsedChunksStatistics::check_sanity() const { + assert(_overhead == (Metachunk::overhead() * _num), "Sanity: Overhead."); + assert(_cap == _used + _free + _waste + _overhead, "Sanity: Capacity."); +} +#endif + +// SpaceManagerStatistics methods + +SpaceManagerStatistics::SpaceManagerStatistics() { reset(); } + +void SpaceManagerStatistics::reset() { + for (int i = 0; i < NumberOfInUseLists; i ++) { + _chunk_stats[i].reset(); + _free_blocks_num = 0; _free_blocks_cap_words = 0; + } +} + +void SpaceManagerStatistics::add_free_blocks_info(uintx num, size_t cap) { + _free_blocks_num += num; + _free_blocks_cap_words += cap; +} + +void SpaceManagerStatistics::add(const SpaceManagerStatistics& other) { + for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { + _chunk_stats[i].add(other._chunk_stats[i]); + } + _free_blocks_num += other._free_blocks_num; + _free_blocks_cap_words += other._free_blocks_cap_words; +} + +// Returns total chunk statistics over all chunk types. +UsedChunksStatistics SpaceManagerStatistics::totals() const { + UsedChunksStatistics stat; + for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { + stat.add(_chunk_stats[i]); + } + return stat; +} + +void SpaceManagerStatistics::print_on(outputStream* st, size_t scale, bool detailed) const { + streamIndentor sti(st); + if (detailed) { + st->cr_indent(); + st->print("Usage by chunk type:"); + { + streamIndentor sti2(st); + for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { + st->cr_indent(); + st->print("%15s: ", chunk_size_name(i)); + if (_chunk_stats[i].num() == 0) { + st->print(" (none)"); + } else { + _chunk_stats[i].print_on(st, scale); + } + } + + st->cr_indent(); + st->print("%15s: ", "-total-"); + totals().print_on(st, scale); + } + if (_free_blocks_num > 0) { + st->cr_indent(); + st->print("deallocated: " UINTX_FORMAT " blocks with ", _free_blocks_num); + print_scaled_words(st, _free_blocks_cap_words, scale); + } + } else { + totals().print_on(st, scale); + st->print(", "); + st->print("deallocated: " UINTX_FORMAT " blocks with ", _free_blocks_num); + print_scaled_words(st, _free_blocks_cap_words, scale); + } +} + +// ClassLoaderMetaspaceStatistics methods + +ClassLoaderMetaspaceStatistics::ClassLoaderMetaspaceStatistics() { reset(); } + +void ClassLoaderMetaspaceStatistics::reset() { + nonclass_sm_stats().reset(); + if (Metaspace::using_class_space()) { + class_sm_stats().reset(); + } +} + +// Returns total space manager statistics for both class and non-class metaspace +SpaceManagerStatistics ClassLoaderMetaspaceStatistics::totals() const { + SpaceManagerStatistics stats; + stats.add(nonclass_sm_stats()); + if (Metaspace::using_class_space()) { + stats.add(class_sm_stats()); + } + return stats; +} + +void ClassLoaderMetaspaceStatistics::add(const ClassLoaderMetaspaceStatistics& other) { + nonclass_sm_stats().add(other.nonclass_sm_stats()); + if (Metaspace::using_class_space()) { + class_sm_stats().add(other.class_sm_stats()); + } +} + +void ClassLoaderMetaspaceStatistics::print_on(outputStream* st, size_t scale, bool detailed) const { + streamIndentor sti(st); + st->cr_indent(); + if (Metaspace::using_class_space()) { + st->print("Non-Class: "); + } + nonclass_sm_stats().print_on(st, scale, detailed); + if (detailed) { + st->cr(); + } + if (Metaspace::using_class_space()) { + st->cr_indent(); + st->print(" Class: "); + class_sm_stats().print_on(st, scale, detailed); + if (detailed) { + st->cr(); + } + st->cr_indent(); + st->print(" Both: "); + totals().print_on(st, scale, detailed); + if (detailed) { + st->cr(); + } + } + st->cr(); +} + + +} // end namespace internals +} // end namespace metaspace + +