# HG changeset patch # User hseigel # Date 1506618636 0 # Node ID 9dfb5791d130bae727d0d54f46958c7541957a88 # Parent bc112140e089756b9c6bda563560ffcfbe4aac1e# Parent 5d20359dd938bfd1b4de71dfc026d5e5ba09281c Merge diff -r bc112140e089 -r 9dfb5791d130 src/hotspot/share/memory/metaspace.cpp --- a/src/hotspot/share/memory/metaspace.cpp Thu Sep 28 13:01:24 2017 -0400 +++ b/src/hotspot/share/memory/metaspace.cpp Thu Sep 28 17:10:36 2017 +0000 @@ -2718,7 +2718,7 @@ size_t MetaspaceAux::_capacity_words[] = {0, 0}; -size_t MetaspaceAux::_used_words[] = {0, 0}; +volatile size_t MetaspaceAux::_used_words[] = {0, 0}; size_t MetaspaceAux::free_bytes(Metaspace::MetadataType mdtype) { VirtualSpaceList* list = Metaspace::get_space_list(mdtype); diff -r bc112140e089 -r 9dfb5791d130 src/hotspot/share/memory/metaspace.hpp --- a/src/hotspot/share/memory/metaspace.hpp Thu Sep 28 13:01:24 2017 -0400 +++ b/src/hotspot/share/memory/metaspace.hpp Thu Sep 28 17:10:36 2017 +0000 @@ -273,7 +273,7 @@ // Running sum of space in all Metachunks that // are being used for metadata. One for each // type of Metadata. - static size_t _used_words[Metaspace:: MetadataTypeCount]; + static volatile size_t _used_words[Metaspace:: MetadataTypeCount]; public: // Decrement and increment _allocated_capacity_words diff -r bc112140e089 -r 9dfb5791d130 src/hotspot/share/services/memBaseline.cpp --- a/src/hotspot/share/services/memBaseline.cpp Thu Sep 28 13:01:24 2017 -0400 +++ b/src/hotspot/share/services/memBaseline.cpp Thu Sep 28 17:10:36 2017 +0000 @@ -144,6 +144,7 @@ bool MemBaseline::baseline_summary() { MallocMemorySummary::snapshot(&_malloc_memory_snapshot); VirtualMemorySummary::snapshot(&_virtual_memory_snapshot); + MetaspaceSnapshot::snapshot(_metaspace_snapshot); return true; } diff -r bc112140e089 -r 9dfb5791d130 src/hotspot/share/services/memBaseline.hpp --- a/src/hotspot/share/services/memBaseline.hpp Thu Sep 28 13:01:24 2017 -0400 +++ b/src/hotspot/share/services/memBaseline.hpp Thu Sep 28 17:10:36 2017 +0000 @@ -65,6 +65,7 @@ // Summary information MallocMemorySnapshot _malloc_memory_snapshot; VirtualMemorySnapshot _virtual_memory_snapshot; + MetaspaceSnapshot _metaspace_snapshot; size_t _class_count; @@ -103,6 +104,10 @@ return &_virtual_memory_snapshot; } + MetaspaceSnapshot* metaspace_snapshot() { + return &_metaspace_snapshot; + } + MallocSiteIterator malloc_sites(SortingOrder order); VirtualMemorySiteIterator virtual_memory_sites(SortingOrder order); diff -r bc112140e089 -r 9dfb5791d130 src/hotspot/share/services/memReporter.cpp --- a/src/hotspot/share/services/memReporter.cpp Thu Sep 28 13:01:24 2017 -0400 +++ b/src/hotspot/share/services/memReporter.cpp Thu Sep 28 17:10:36 2017 +0000 @@ -175,12 +175,44 @@ amount_in_current_scale(_malloc_snapshot->malloc_overhead()->size()) > 0) { out->print_cr("%27s (tracking overhead=" SIZE_FORMAT "%s)", " ", amount_in_current_scale(_malloc_snapshot->malloc_overhead()->size()), scale); + } else if (flag == mtClass) { + // Metadata information + report_metadata(Metaspace::NonClassType); + if (Metaspace::using_class_space()) { + report_metadata(Metaspace::ClassType); + } } - out->print_cr(" "); } } +void MemSummaryReporter::report_metadata(Metaspace::MetadataType type) const { + assert(type == Metaspace::NonClassType || type == Metaspace::ClassType, + "Invalid metadata type"); + const char* name = (type == Metaspace::NonClassType) ? + "Metadata: " : "Class space:"; + + outputStream* out = output(); + const char* scale = current_scale(); + size_t committed = MetaspaceAux::committed_bytes(type); + size_t used = MetaspaceAux::used_bytes(type); + size_t free = (MetaspaceAux::capacity_bytes(type) - used) + + MetaspaceAux::free_chunks_total_bytes(type) + + MetaspaceAux::free_bytes(type); + + assert(committed >= used + free, "Sanity"); + size_t waste = committed - (used + free); + + out->print_cr("%27s ( %s)", " ", name); + out->print("%27s ( ", " "); + print_total(MetaspaceAux::reserved_bytes(type), committed); + out->print_cr(")"); + out->print_cr("%27s ( used=" SIZE_FORMAT "%s)", " ", amount_in_current_scale(used), scale); + out->print_cr("%27s ( free=" SIZE_FORMAT "%s)", " ", amount_in_current_scale(free), scale); + out->print_cr("%27s ( waste=" SIZE_FORMAT "%s =%2.2f%%)", " ", amount_in_current_scale(waste), + scale, ((float)waste * 100)/committed); +} + void MemDetailReporter::report_detail() { // Start detail report outputStream* out = output(); @@ -305,9 +337,13 @@ MEMFLAGS flag = NMTUtil::index_to_flag(index); // thread stack is reported as part of thread category if (flag == mtThreadStack) continue; - diff_summary_of_type(flag, _early_baseline.malloc_memory(flag), - _early_baseline.virtual_memory(flag), _current_baseline.malloc_memory(flag), - _current_baseline.virtual_memory(flag)); + diff_summary_of_type(flag, + _early_baseline.malloc_memory(flag), + _early_baseline.virtual_memory(flag), + _early_baseline.metaspace_snapshot(), + _current_baseline.malloc_memory(flag), + _current_baseline.virtual_memory(flag), + _current_baseline.metaspace_snapshot()); } } @@ -367,9 +403,11 @@ } -void MemSummaryDiffReporter::diff_summary_of_type(MEMFLAGS flag, const MallocMemory* early_malloc, - const VirtualMemory* early_vm, const MallocMemory* current_malloc, - const VirtualMemory* current_vm) const { +void MemSummaryDiffReporter::diff_summary_of_type(MEMFLAGS flag, + const MallocMemory* early_malloc, const VirtualMemory* early_vm, + const MetaspaceSnapshot* early_ms, + const MallocMemory* current_malloc, const VirtualMemory* current_vm, + const MetaspaceSnapshot* current_ms) const { outputStream* out = output(); const char* scale = current_scale(); @@ -486,11 +524,77 @@ out->print(" %+ld%s", overhead_diff, scale); } out->print_cr(")"); + } else if (flag == mtClass) { + assert(current_ms != NULL && early_ms != NULL, "Sanity"); + print_metaspace_diff(current_ms, early_ms); } out->print_cr(" "); } } +void MemSummaryDiffReporter::print_metaspace_diff(const MetaspaceSnapshot* current_ms, + const MetaspaceSnapshot* early_ms) const { + print_metaspace_diff(Metaspace::NonClassType, current_ms, early_ms); + if (Metaspace::using_class_space()) { + print_metaspace_diff(Metaspace::ClassType, current_ms, early_ms); + } +} + +void MemSummaryDiffReporter::print_metaspace_diff(Metaspace::MetadataType type, + const MetaspaceSnapshot* current_ms, + const MetaspaceSnapshot* early_ms) const { + const char* name = (type == Metaspace::NonClassType) ? + "Metadata: " : "Class space:"; + + outputStream* out = output(); + const char* scale = current_scale(); + + out->print_cr("%27s ( %s)", " ", name); + out->print("%27s ( ", " "); + print_virtual_memory_diff(current_ms->reserved_in_bytes(type), + current_ms->committed_in_bytes(type), + early_ms->reserved_in_bytes(type), + early_ms->committed_in_bytes(type)); + out->print_cr(")"); + + long diff_used = diff_in_current_scale(current_ms->used_in_bytes(type), + early_ms->used_in_bytes(type)); + long diff_free = diff_in_current_scale(current_ms->free_in_bytes(type), + early_ms->free_in_bytes(type)); + + size_t current_waste = current_ms->committed_in_bytes(type) + - (current_ms->used_in_bytes(type) + current_ms->free_in_bytes(type)); + size_t early_waste = early_ms->committed_in_bytes(type) + - (early_ms->used_in_bytes(type) + early_ms->free_in_bytes(type)); + long diff_waste = diff_in_current_scale(current_waste, early_waste); + + // Diff used + out->print("%27s ( used=" SIZE_FORMAT "%s", " ", + amount_in_current_scale(current_ms->used_in_bytes(type)), scale); + if (diff_used != 0) { + out->print(" %+ld%s", diff_used, scale); + } + out->print_cr(")"); + + // Diff free + out->print("%27s ( free=" SIZE_FORMAT "%s", " ", + amount_in_current_scale(current_ms->free_in_bytes(type)), scale); + if (diff_free != 0) { + out->print(" %+ld%s", diff_free, scale); + } + out->print_cr(")"); + + + // Diff waste + out->print("%27s ( waste=" SIZE_FORMAT "%s =%2.2f%%", " ", + amount_in_current_scale(current_waste), scale, + ((float)current_waste * 100) / current_ms->committed_in_bytes(type)); + if (diff_waste != 0) { + out->print(" %+ld%s", diff_waste, scale); + } + out->print_cr(")"); +} + void MemDetailDiffReporter::report_diff() { MemSummaryDiffReporter::report_diff(); diff_malloc_sites(); diff -r bc112140e089 -r 9dfb5791d130 src/hotspot/share/services/memReporter.hpp --- a/src/hotspot/share/services/memReporter.hpp Thu Sep 28 13:01:24 2017 -0400 +++ b/src/hotspot/share/services/memReporter.hpp Thu Sep 28 17:10:36 2017 +0000 @@ -27,6 +27,7 @@ #if INCLUDE_NMT +#include "memory/metaspace.hpp" #include "oops/instanceKlass.hpp" #include "services/memBaseline.hpp" #include "services/nmtCommon.hpp" @@ -110,6 +111,8 @@ // Report summary for each memory type void report_summary_of_type(MEMFLAGS type, MallocMemory* malloc_memory, VirtualMemory* virtual_memory); + + void report_metadata(Metaspace::MetadataType type) const; }; /* @@ -170,7 +173,9 @@ // report the comparison of each memory type void diff_summary_of_type(MEMFLAGS type, const MallocMemory* early_malloc, const VirtualMemory* early_vm, - const MallocMemory* current_malloc, const VirtualMemory* current_vm) const; + const MetaspaceSnapshot* early_ms, + const MallocMemory* current_malloc, const VirtualMemory* current_vm, + const MetaspaceSnapshot* current_ms) const; protected: void print_malloc_diff(size_t current_amount, size_t current_count, @@ -179,6 +184,11 @@ size_t early_reserved, size_t early_committed) const; void print_arena_diff(size_t current_amount, size_t current_count, size_t early_amount, size_t early_count) const; + + void print_metaspace_diff(const MetaspaceSnapshot* current_ms, + const MetaspaceSnapshot* early_ms) const; + void print_metaspace_diff(Metaspace::MetadataType type, + const MetaspaceSnapshot* current_ms, const MetaspaceSnapshot* early_ms) const; }; /* diff -r bc112140e089 -r 9dfb5791d130 src/hotspot/share/services/virtualMemoryTracker.cpp --- a/src/hotspot/share/services/virtualMemoryTracker.cpp Thu Sep 28 13:01:24 2017 -0400 +++ b/src/hotspot/share/services/virtualMemoryTracker.cpp Thu Sep 28 17:10:36 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2017, Oracle 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 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "memory/metaspace.hpp" #include "runtime/atomic.hpp" #include "runtime/os.hpp" #include "runtime/threadCritical.hpp" @@ -492,3 +493,35 @@ return true; } + +// Metaspace Support +MetaspaceSnapshot::MetaspaceSnapshot() { + for (int index = (int)Metaspace::ClassType; index < (int)Metaspace::MetadataTypeCount; index ++) { + Metaspace::MetadataType type = (Metaspace::MetadataType)index; + assert_valid_metadata_type(type); + _reserved_in_bytes[type] = 0; + _committed_in_bytes[type] = 0; + _used_in_bytes[type] = 0; + _free_in_bytes[type] = 0; + } +} + +void MetaspaceSnapshot::snapshot(Metaspace::MetadataType type, MetaspaceSnapshot& mss) { + assert_valid_metadata_type(type); + + mss._reserved_in_bytes[type] = MetaspaceAux::reserved_bytes(type); + mss._committed_in_bytes[type] = MetaspaceAux::committed_bytes(type); + mss._used_in_bytes[type] = MetaspaceAux::used_bytes(type); + + size_t free_in_bytes = (MetaspaceAux::capacity_bytes(type) - MetaspaceAux::used_bytes(type)) + + MetaspaceAux::free_chunks_total_bytes(type) + + MetaspaceAux::free_bytes(type); + mss._free_in_bytes[type] = free_in_bytes; +} + +void MetaspaceSnapshot::snapshot(MetaspaceSnapshot& mss) { + snapshot(Metaspace::ClassType, mss); + if (Metaspace::using_class_space()) { + snapshot(Metaspace::NonClassType, mss); + } +} diff -r bc112140e089 -r 9dfb5791d130 src/hotspot/share/services/virtualMemoryTracker.hpp --- a/src/hotspot/share/services/virtualMemoryTracker.hpp Thu Sep 28 13:01:24 2017 -0400 +++ b/src/hotspot/share/services/virtualMemoryTracker.hpp Thu Sep 28 17:10:36 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2017, Oracle 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 @@ -28,6 +28,7 @@ #if INCLUDE_NMT #include "memory/allocation.hpp" +#include "memory/metaspace.hpp" #include "services/allocationSite.hpp" #include "services/nmtCommon.hpp" #include "utilities/linkedlist.hpp" @@ -419,6 +420,31 @@ }; +class MetaspaceSnapshot : public ResourceObj { +private: + size_t _reserved_in_bytes[Metaspace::MetadataTypeCount]; + size_t _committed_in_bytes[Metaspace::MetadataTypeCount]; + size_t _used_in_bytes[Metaspace::MetadataTypeCount]; + size_t _free_in_bytes[Metaspace::MetadataTypeCount]; + +public: + MetaspaceSnapshot(); + size_t reserved_in_bytes(Metaspace::MetadataType type) const { assert_valid_metadata_type(type); return _reserved_in_bytes[type]; } + size_t committed_in_bytes(Metaspace::MetadataType type) const { assert_valid_metadata_type(type); return _committed_in_bytes[type]; } + size_t used_in_bytes(Metaspace::MetadataType type) const { assert_valid_metadata_type(type); return _used_in_bytes[type]; } + size_t free_in_bytes(Metaspace::MetadataType type) const { assert_valid_metadata_type(type); return _free_in_bytes[type]; } + + static void snapshot(MetaspaceSnapshot& s); + +private: + static void snapshot(Metaspace::MetadataType type, MetaspaceSnapshot& s); + + static void assert_valid_metadata_type(Metaspace::MetadataType type) { + assert(type == Metaspace::ClassType || type == Metaspace::NonClassType, + "Invalid metadata type"); + } +}; + #endif // INCLUDE_NMT #endif // SHARE_VM_SERVICES_VIRTUAL_MEMORY_TRACKER_HPP