1 /*
   2  * Copyright (c) 2012, 2018, Oracle and/or its affiliates. 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 it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 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 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_VM_SERVICES_MEM_BASELINE_HPP
  26 #define SHARE_VM_SERVICES_MEM_BASELINE_HPP
  27 
  28 #if INCLUDE_NMT
  29 
  30 #include "runtime/mutex.hpp"
  31 #include "services/mallocSiteTable.hpp"
  32 #include "services/mallocTracker.hpp"
  33 #include "services/nmtCommon.hpp"
  34 #include "services/virtualMemoryTracker.hpp"
  35 #include "utilities/linkedlist.hpp"
  36 
  37 typedef LinkedListIterator<MallocSite>                   MallocSiteIterator;
  38 typedef LinkedListIterator<VirtualMemoryAllocationSite>  VirtualMemorySiteIterator;
  39 typedef LinkedListIterator<ReservedMemoryRegion>         VirtualMemoryAllocationIterator;
  40 
  41 /*
  42  * Baseline a memory snapshot
  43  */
  44 class MemBaseline {
  45  public:
  46   enum BaselineThreshold {
  47     SIZE_THRESHOLD = K        // Only allocation size over this threshold will be baselined.
  48   };
  49 
  50   enum BaselineType {
  51     Not_baselined,
  52     Summary_baselined,
  53     Detail_baselined
  54   };
  55 
  56   enum SortingOrder {
  57     by_address,      // by memory address
  58     by_size,         // by memory size
  59     by_site,         // by call site where the memory is allocated from
  60     by_site_and_type // by call site and memory type
  61   };
  62 
  63  private:
  64   // Summary information
  65   MallocMemorySnapshot   _malloc_memory_snapshot;
  66   VirtualMemorySnapshot  _virtual_memory_snapshot;
  67   MetaspaceSnapshot      _metaspace_snapshot;
  68 
  69   size_t                 _instance_class_count;
  70   size_t                 _array_class_count;
  71 
  72   // Allocation sites information
  73   // Malloc allocation sites
  74   LinkedListImpl<MallocSite>                  _malloc_sites;
  75 
  76   // All virtual memory allocations
  77   LinkedListImpl<ReservedMemoryRegion>        _virtual_memory_allocations;
  78 
  79   // Virtual memory allocations by allocation sites, always in by_address
  80   // order
  81   LinkedListImpl<VirtualMemoryAllocationSite> _virtual_memory_sites;
  82 
  83   SortingOrder         _malloc_sites_order;
  84   SortingOrder         _virtual_memory_sites_order;
  85 
  86   BaselineType         _baseline_type;
  87 
  88  public:
  89   // create a memory baseline
  90   MemBaseline():
  91     _baseline_type(Not_baselined),
  92     _instance_class_count(0), _array_class_count(0) {
  93   }
  94 
  95   bool baseline(bool summaryOnly = true);
  96 
  97   BaselineType baseline_type() const { return _baseline_type; }
  98 
  99   MallocMemorySnapshot* malloc_memory_snapshot() {
 100     return &_malloc_memory_snapshot;
 101   }
 102 
 103   VirtualMemorySnapshot* virtual_memory_snapshot() {
 104     return &_virtual_memory_snapshot;
 105   }
 106 
 107   MetaspaceSnapshot* metaspace_snapshot() {
 108     return &_metaspace_snapshot;
 109   }
 110 
 111   MallocSiteIterator malloc_sites(SortingOrder order);
 112   VirtualMemorySiteIterator virtual_memory_sites(SortingOrder order);
 113 
 114   // Virtual memory allocation iterator always returns in virtual memory
 115   // base address order.
 116   VirtualMemoryAllocationIterator virtual_memory_allocations() {
 117     assert(!_virtual_memory_allocations.is_empty(), "Not detail baseline");
 118     return VirtualMemoryAllocationIterator(_virtual_memory_allocations.head());
 119   }
 120 
 121   // Total reserved memory = total malloc'd memory + total reserved virtual
 122   // memory
 123   size_t total_reserved_memory() const {
 124     assert(baseline_type() != Not_baselined, "Not yet baselined");
 125     size_t amount = _malloc_memory_snapshot.total() +
 126            _virtual_memory_snapshot.total_reserved();
 127     return amount;
 128   }
 129 
 130   // Total committed memory = total malloc'd memory + total committed
 131   // virtual memory
 132   size_t total_committed_memory() const {
 133     assert(baseline_type() != Not_baselined, "Not yet baselined");
 134     size_t amount = _malloc_memory_snapshot.total() +
 135            _virtual_memory_snapshot.total_committed();
 136     return amount;
 137   }
 138 
 139   size_t total_arena_memory() const {
 140     assert(baseline_type() != Not_baselined, "Not yet baselined");
 141     return _malloc_memory_snapshot.total_arena();
 142   }
 143 
 144   size_t malloc_tracking_overhead() const {
 145     assert(baseline_type() != Not_baselined, "Not yet baselined");
 146     MemBaseline* bl = const_cast<MemBaseline*>(this);
 147     return bl->_malloc_memory_snapshot.malloc_overhead()->size();
 148   }
 149 
 150   MallocMemory* malloc_memory(MEMFLAGS flag) {
 151     assert(baseline_type() != Not_baselined, "Not yet baselined");
 152     return _malloc_memory_snapshot.by_type(flag);
 153   }
 154 
 155   VirtualMemory* virtual_memory(MEMFLAGS flag) {
 156     assert(baseline_type() != Not_baselined, "Not yet baselined");
 157     return _virtual_memory_snapshot.by_type(flag);
 158   }
 159 
 160 
 161   size_t class_count() const {
 162     assert(baseline_type() != Not_baselined, "Not yet baselined");
 163     return _instance_class_count + _array_class_count;
 164   }
 165 
 166   size_t instance_class_count() const {
 167     assert(baseline_type() != Not_baselined, "Not yet baselined");
 168     return _instance_class_count;
 169   }
 170 
 171   size_t array_class_count() const {
 172     assert(baseline_type() != Not_baselined, "Not yet baselined");
 173     return _array_class_count;
 174   }
 175 
 176   size_t thread_count() const {
 177     assert(baseline_type() != Not_baselined, "Not yet baselined");
 178     return _malloc_memory_snapshot.thread_count();
 179   }
 180 
 181   // reset the baseline for reuse
 182   void reset() {
 183     _baseline_type = Not_baselined;
 184     // _malloc_memory_snapshot and _virtual_memory_snapshot are copied over.
 185     _instance_class_count  = 0;
 186     _array_class_count = 0;
 187 
 188     _malloc_sites.clear();
 189     _virtual_memory_sites.clear();
 190     _virtual_memory_allocations.clear();
 191   }
 192 
 193  private:
 194   // Baseline summary information
 195   bool baseline_summary();
 196 
 197   // Baseline allocation sites (detail tracking only)
 198   bool baseline_allocation_sites();
 199 
 200   // Aggregate virtual memory allocation by allocation sites
 201   bool aggregate_virtual_memory_allocation_sites();
 202 
 203   // Sorting allocation sites in different orders
 204   // Sort allocation sites in size order
 205   void malloc_sites_to_size_order();
 206   // Sort allocation sites in call site address order
 207   void malloc_sites_to_allocation_site_order();
 208   // Sort allocation sites in call site address and memory type order
 209   void malloc_sites_to_allocation_site_and_type_order();
 210 
 211   // Sort allocation sites in reserved size order
 212   void virtual_memory_sites_to_size_order();
 213   // Sort allocation sites in call site address order
 214   void virtual_memory_sites_to_reservation_site_order();
 215 };
 216 
 217 #endif // INCLUDE_NMT
 218 
 219 #endif // SHARE_VM_SERVICES_MEM_BASELINE_HPP