Path: blob/master/src/hotspot/share/services/memBaseline.cpp
41144 views
/*1* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/23#include "precompiled.hpp"2425#include "classfile/classLoaderDataGraph.inline.hpp"26#include "memory/allocation.hpp"27#include "memory/metaspaceUtils.hpp"28#include "runtime/safepoint.hpp"29#include "runtime/thread.inline.hpp"30#include "services/memBaseline.hpp"31#include "services/memTracker.hpp"3233/*34* Sizes are sorted in descenting order for reporting35*/36int compare_malloc_size(const MallocSite& s1, const MallocSite& s2) {37if (s1.size() == s2.size()) {38return 0;39} else if (s1.size() > s2.size()) {40return -1;41} else {42return 1;43}44}454647int compare_virtual_memory_size(const VirtualMemoryAllocationSite& s1,48const VirtualMemoryAllocationSite& s2) {49if (s1.reserved() == s2.reserved()) {50return 0;51} else if (s1.reserved() > s2.reserved()) {52return -1;53} else {54return 1;55}56}5758// Sort into allocation site addresses order for baseline comparison59int compare_malloc_site(const MallocSite& s1, const MallocSite& s2) {60return s1.call_stack()->compare(*s2.call_stack());61}6263// Sort into allocation site addresses and memory type order for baseline comparison64int compare_malloc_site_and_type(const MallocSite& s1, const MallocSite& s2) {65int res = compare_malloc_site(s1, s2);66if (res == 0) {67res = (int)(NMTUtil::flag_to_index(s1.flag()) - NMTUtil::flag_to_index(s2.flag()));68}6970return res;71}7273int compare_virtual_memory_site(const VirtualMemoryAllocationSite& s1,74const VirtualMemoryAllocationSite& s2) {75return s1.call_stack()->compare(*s2.call_stack());76}7778/*79* Walker to walk malloc allocation site table80*/81class MallocAllocationSiteWalker : public MallocSiteWalker {82private:83SortedLinkedList<MallocSite, compare_malloc_size> _malloc_sites;84size_t _count;8586// Entries in MallocSiteTable with size = 0 and count = 0,87// when the malloc site is not longer there.88public:89MallocAllocationSiteWalker() : _count(0) { }9091inline size_t count() const { return _count; }9293LinkedList<MallocSite>* malloc_sites() {94return &_malloc_sites;95}9697bool do_malloc_site(const MallocSite* site) {98if (site->size() > 0) {99if (_malloc_sites.add(*site) != NULL) {100_count++;101return true;102} else {103return false; // OOM104}105} else {106// Ignore empty sites.107return true;108}109}110};111112// Compare virtual memory region's base address113int compare_virtual_memory_base(const ReservedMemoryRegion& r1, const ReservedMemoryRegion& r2) {114return r1.compare(r2);115}116117// Walk all virtual memory regions for baselining118class VirtualMemoryAllocationWalker : public VirtualMemoryWalker {119private:120SortedLinkedList<ReservedMemoryRegion, compare_virtual_memory_base>121_virtual_memory_regions;122size_t _count;123124public:125VirtualMemoryAllocationWalker() : _count(0) { }126127bool do_allocation_site(const ReservedMemoryRegion* rgn) {128if (rgn->size() > 0) {129if (_virtual_memory_regions.add(*rgn) != NULL) {130_count ++;131return true;132} else {133return false;134}135} else {136// Ignore empty sites.137return true;138}139}140141LinkedList<ReservedMemoryRegion>* virtual_memory_allocations() {142return &_virtual_memory_regions;143}144};145146147bool MemBaseline::baseline_summary() {148MallocMemorySummary::snapshot(&_malloc_memory_snapshot);149VirtualMemorySummary::snapshot(&_virtual_memory_snapshot);150_metaspace_stats = MetaspaceUtils::get_combined_statistics();151return true;152}153154bool MemBaseline::baseline_allocation_sites() {155// Malloc allocation sites156MallocAllocationSiteWalker malloc_walker;157if (!MallocSiteTable::walk_malloc_site(&malloc_walker)) {158return false;159}160161// Walk simple thread stacks162if (!ThreadStackTracker::walk_simple_thread_stack_site(&malloc_walker)) {163return false;164}165166_malloc_sites.move(malloc_walker.malloc_sites());167// The malloc sites are collected in size order168_malloc_sites_order = by_size;169170// Virtual memory allocation sites171VirtualMemoryAllocationWalker virtual_memory_walker;172if (!VirtualMemoryTracker::walk_virtual_memory(&virtual_memory_walker)) {173return false;174}175176// Virtual memory allocations are collected in call stack order177_virtual_memory_allocations.move(virtual_memory_walker.virtual_memory_allocations());178179if (!aggregate_virtual_memory_allocation_sites()) {180return false;181}182// Virtual memory allocation sites are aggregrated in call stack order183_virtual_memory_sites_order = by_address;184185return true;186}187188bool MemBaseline::baseline(bool summaryOnly) {189reset();190191_instance_class_count = ClassLoaderDataGraph::num_instance_classes();192_array_class_count = ClassLoaderDataGraph::num_array_classes();193194if (!baseline_summary()) {195return false;196}197198_baseline_type = Summary_baselined;199200// baseline details201if (!summaryOnly &&202MemTracker::tracking_level() == NMT_detail) {203baseline_allocation_sites();204_baseline_type = Detail_baselined;205}206207return true;208}209210int compare_allocation_site(const VirtualMemoryAllocationSite& s1,211const VirtualMemoryAllocationSite& s2) {212return s1.call_stack()->compare(*s2.call_stack());213}214215bool MemBaseline::aggregate_virtual_memory_allocation_sites() {216SortedLinkedList<VirtualMemoryAllocationSite, compare_allocation_site> allocation_sites;217218VirtualMemoryAllocationIterator itr = virtual_memory_allocations();219const ReservedMemoryRegion* rgn;220VirtualMemoryAllocationSite* site;221while ((rgn = itr.next()) != NULL) {222VirtualMemoryAllocationSite tmp(*rgn->call_stack(), rgn->flag());223site = allocation_sites.find(tmp);224if (site == NULL) {225LinkedListNode<VirtualMemoryAllocationSite>* node =226allocation_sites.add(tmp);227if (node == NULL) return false;228site = node->data();229}230site->reserve_memory(rgn->size());231site->commit_memory(rgn->committed_size());232}233234_virtual_memory_sites.move(&allocation_sites);235return true;236}237238MallocSiteIterator MemBaseline::malloc_sites(SortingOrder order) {239assert(!_malloc_sites.is_empty(), "Not detail baseline");240switch(order) {241case by_size:242malloc_sites_to_size_order();243break;244case by_site:245malloc_sites_to_allocation_site_order();246break;247case by_site_and_type:248malloc_sites_to_allocation_site_and_type_order();249break;250case by_address:251default:252ShouldNotReachHere();253}254return MallocSiteIterator(_malloc_sites.head());255}256257VirtualMemorySiteIterator MemBaseline::virtual_memory_sites(SortingOrder order) {258assert(!_virtual_memory_sites.is_empty(), "Not detail baseline");259switch(order) {260case by_size:261virtual_memory_sites_to_size_order();262break;263case by_site:264virtual_memory_sites_to_reservation_site_order();265break;266case by_address:267default:268ShouldNotReachHere();269}270return VirtualMemorySiteIterator(_virtual_memory_sites.head());271}272273274// Sorting allocations sites in different orders275void MemBaseline::malloc_sites_to_size_order() {276if (_malloc_sites_order != by_size) {277SortedLinkedList<MallocSite, compare_malloc_size> tmp;278279// Add malloc sites to sorted linked list to sort into size order280tmp.move(&_malloc_sites);281_malloc_sites.set_head(tmp.head());282tmp.set_head(NULL);283_malloc_sites_order = by_size;284}285}286287void MemBaseline::malloc_sites_to_allocation_site_order() {288if (_malloc_sites_order != by_site && _malloc_sites_order != by_site_and_type) {289SortedLinkedList<MallocSite, compare_malloc_site> tmp;290// Add malloc sites to sorted linked list to sort into site (address) order291tmp.move(&_malloc_sites);292_malloc_sites.set_head(tmp.head());293tmp.set_head(NULL);294_malloc_sites_order = by_site;295}296}297298void MemBaseline::malloc_sites_to_allocation_site_and_type_order() {299if (_malloc_sites_order != by_site_and_type) {300SortedLinkedList<MallocSite, compare_malloc_site_and_type> tmp;301// Add malloc sites to sorted linked list to sort into site (address) order302tmp.move(&_malloc_sites);303_malloc_sites.set_head(tmp.head());304tmp.set_head(NULL);305_malloc_sites_order = by_site_and_type;306}307}308309void MemBaseline::virtual_memory_sites_to_size_order() {310if (_virtual_memory_sites_order != by_size) {311SortedLinkedList<VirtualMemoryAllocationSite, compare_virtual_memory_size> tmp;312313tmp.move(&_virtual_memory_sites);314315_virtual_memory_sites.set_head(tmp.head());316tmp.set_head(NULL);317_virtual_memory_sites_order = by_size;318}319}320321void MemBaseline::virtual_memory_sites_to_reservation_site_order() {322if (_virtual_memory_sites_order != by_size) {323SortedLinkedList<VirtualMemoryAllocationSite, compare_virtual_memory_site> tmp;324325tmp.move(&_virtual_memory_sites);326327_virtual_memory_sites.set_head(tmp.head());328tmp.set_head(NULL);329330_virtual_memory_sites_order = by_size;331}332}333334335336