1.1 --- a/src/share/vm/services/memBaseline.hpp Wed Aug 27 09:36:55 2014 +0200 1.2 +++ b/src/share/vm/services/memBaseline.hpp Wed Aug 27 08:19:12 2014 -0400 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -25,425 +25,205 @@ 1.11 #ifndef SHARE_VM_SERVICES_MEM_BASELINE_HPP 1.12 #define SHARE_VM_SERVICES_MEM_BASELINE_HPP 1.13 1.14 +#if INCLUDE_NMT 1.15 + 1.16 #include "memory/allocation.hpp" 1.17 #include "runtime/mutex.hpp" 1.18 -#include "services/memPtr.hpp" 1.19 -#include "services/memSnapshot.hpp" 1.20 +#include "services/mallocSiteTable.hpp" 1.21 +#include "services/mallocTracker.hpp" 1.22 +#include "services/nmtCommon.hpp" 1.23 +#include "services/virtualMemoryTracker.hpp" 1.24 +#include "utilities/linkedlist.hpp" 1.25 1.26 -// compare unsigned number 1.27 -#define UNSIGNED_COMPARE(a, b) ((a > b) ? 1 : ((a == b) ? 0 : -1)) 1.28 +typedef LinkedListIterator<MallocSite> MallocSiteIterator; 1.29 +typedef LinkedListIterator<VirtualMemoryAllocationSite> VirtualMemorySiteIterator; 1.30 +typedef LinkedListIterator<ReservedMemoryRegion> VirtualMemoryAllocationIterator; 1.31 1.32 /* 1.33 - * MallocCallsitePointer and VMCallsitePointer are used 1.34 - * to baseline memory blocks with their callsite information. 1.35 - * They are only available when detail tracking is turned 1.36 - * on. 1.37 + * Baseline a memory snapshot 1.38 */ 1.39 - 1.40 -/* baselined malloc record aggregated by callsite */ 1.41 -class MallocCallsitePointer : public MemPointer { 1.42 - private: 1.43 - size_t _count; // number of malloc invocation from this callsite 1.44 - size_t _amount; // total amount of memory malloc-ed from this callsite 1.45 - 1.46 +class MemBaseline VALUE_OBJ_CLASS_SPEC { 1.47 public: 1.48 - MallocCallsitePointer() { 1.49 - _count = 0; 1.50 - _amount = 0; 1.51 - } 1.52 - 1.53 - MallocCallsitePointer(address pc) : MemPointer(pc) { 1.54 - _count = 0; 1.55 - _amount = 0; 1.56 - } 1.57 - 1.58 - MallocCallsitePointer& operator=(const MallocCallsitePointer& p) { 1.59 - MemPointer::operator=(p); 1.60 - _count = p.count(); 1.61 - _amount = p.amount(); 1.62 - return *this; 1.63 - } 1.64 - 1.65 - inline void inc(size_t size) { 1.66 - _count ++; 1.67 - _amount += size; 1.68 + enum BaselineThreshold { 1.69 + SIZE_THRESHOLD = K // Only allocation size over this threshold will be baselined. 1.70 }; 1.71 1.72 - inline size_t count() const { 1.73 - return _count; 1.74 - } 1.75 + enum BaselineType { 1.76 + Not_baselined, 1.77 + Summary_baselined, 1.78 + Detail_baselined 1.79 + }; 1.80 1.81 - inline size_t amount() const { 1.82 - return _amount; 1.83 - } 1.84 -}; 1.85 - 1.86 -// baselined virtual memory record aggregated by callsite 1.87 -class VMCallsitePointer : public MemPointer { 1.88 - private: 1.89 - size_t _count; // number of invocation from this callsite 1.90 - size_t _reserved_amount; // total reserved amount 1.91 - size_t _committed_amount; // total committed amount 1.92 - 1.93 - public: 1.94 - VMCallsitePointer() { 1.95 - _count = 0; 1.96 - _reserved_amount = 0; 1.97 - _committed_amount = 0; 1.98 - } 1.99 - 1.100 - VMCallsitePointer(address pc) : MemPointer(pc) { 1.101 - _count = 0; 1.102 - _reserved_amount = 0; 1.103 - _committed_amount = 0; 1.104 - } 1.105 - 1.106 - VMCallsitePointer& operator=(const VMCallsitePointer& p) { 1.107 - MemPointer::operator=(p); 1.108 - _count = p.count(); 1.109 - _reserved_amount = p.reserved_amount(); 1.110 - _committed_amount = p.committed_amount(); 1.111 - return *this; 1.112 - } 1.113 - 1.114 - inline void inc(size_t reserved, size_t committed) { 1.115 - _count ++; 1.116 - _reserved_amount += reserved; 1.117 - _committed_amount += committed; 1.118 - } 1.119 - 1.120 - inline size_t count() const { 1.121 - return _count; 1.122 - } 1.123 - 1.124 - inline size_t reserved_amount() const { 1.125 - return _reserved_amount; 1.126 - } 1.127 - 1.128 - inline size_t committed_amount() const { 1.129 - return _committed_amount; 1.130 - } 1.131 -}; 1.132 - 1.133 -// maps a memory type flag to readable name 1.134 -typedef struct _memType2Name { 1.135 - MEMFLAGS _flag; 1.136 - const char* _name; 1.137 -} MemType2Name; 1.138 - 1.139 - 1.140 -// This class aggregates malloc'd records by memory type 1.141 -class MallocMem VALUE_OBJ_CLASS_SPEC { 1.142 - private: 1.143 - MEMFLAGS _type; 1.144 - 1.145 - size_t _count; 1.146 - size_t _amount; 1.147 - 1.148 - public: 1.149 - MallocMem() { 1.150 - _type = mtNone; 1.151 - _count = 0; 1.152 - _amount = 0; 1.153 - } 1.154 - 1.155 - MallocMem(MEMFLAGS flags) { 1.156 - assert(HAS_VALID_MEMORY_TYPE(flags), "no type"); 1.157 - _type = FLAGS_TO_MEMORY_TYPE(flags); 1.158 - _count = 0; 1.159 - _amount = 0; 1.160 - } 1.161 - 1.162 - inline void set_type(MEMFLAGS flag) { 1.163 - _type = flag; 1.164 - } 1.165 - 1.166 - inline void clear() { 1.167 - _count = 0; 1.168 - _amount = 0; 1.169 - _type = mtNone; 1.170 - } 1.171 - 1.172 - MallocMem& operator=(const MallocMem& m) { 1.173 - assert(_type == m.type(), "different type"); 1.174 - _count = m.count(); 1.175 - _amount = m.amount(); 1.176 - return *this; 1.177 - } 1.178 - 1.179 - inline void inc(size_t amt) { 1.180 - _amount += amt; 1.181 - _count ++; 1.182 - } 1.183 - 1.184 - inline void reduce(size_t amt) { 1.185 - assert(_amount >= amt, "Just check"); 1.186 - _amount -= amt; 1.187 - } 1.188 - 1.189 - inline void overwrite_counter(size_t count) { 1.190 - _count = count; 1.191 - } 1.192 - 1.193 - inline MEMFLAGS type() const { 1.194 - return _type; 1.195 - } 1.196 - 1.197 - inline bool is_type(MEMFLAGS flags) const { 1.198 - return FLAGS_TO_MEMORY_TYPE(flags) == _type; 1.199 - } 1.200 - 1.201 - inline size_t count() const { 1.202 - return _count; 1.203 - } 1.204 - 1.205 - inline size_t amount() const { 1.206 - return _amount; 1.207 - } 1.208 -}; 1.209 - 1.210 -// This class records live arena's memory usage 1.211 -class ArenaMem : public MallocMem { 1.212 - public: 1.213 - ArenaMem(MEMFLAGS typeflag): MallocMem(typeflag) { 1.214 - } 1.215 - ArenaMem() { } 1.216 -}; 1.217 - 1.218 -// This class aggregates virtual memory by its memory type 1.219 -class VMMem VALUE_OBJ_CLASS_SPEC { 1.220 - private: 1.221 - MEMFLAGS _type; 1.222 - 1.223 - size_t _count; 1.224 - size_t _reserved_amount; 1.225 - size_t _committed_amount; 1.226 - 1.227 - public: 1.228 - VMMem() { 1.229 - _type = mtNone; 1.230 - _count = 0; 1.231 - _reserved_amount = 0; 1.232 - _committed_amount = 0; 1.233 - } 1.234 - 1.235 - VMMem(MEMFLAGS flags) { 1.236 - assert(HAS_VALID_MEMORY_TYPE(flags), "no type"); 1.237 - _type = FLAGS_TO_MEMORY_TYPE(flags); 1.238 - _count = 0; 1.239 - _reserved_amount = 0; 1.240 - _committed_amount = 0; 1.241 - } 1.242 - 1.243 - inline void clear() { 1.244 - _type = mtNone; 1.245 - _count = 0; 1.246 - _reserved_amount = 0; 1.247 - _committed_amount = 0; 1.248 - } 1.249 - 1.250 - inline void set_type(MEMFLAGS flags) { 1.251 - _type = FLAGS_TO_MEMORY_TYPE(flags); 1.252 - } 1.253 - 1.254 - VMMem& operator=(const VMMem& m) { 1.255 - assert(_type == m.type(), "different type"); 1.256 - 1.257 - _count = m.count(); 1.258 - _reserved_amount = m.reserved_amount(); 1.259 - _committed_amount = m.committed_amount(); 1.260 - return *this; 1.261 - } 1.262 - 1.263 - 1.264 - inline MEMFLAGS type() const { 1.265 - return _type; 1.266 - } 1.267 - 1.268 - inline bool is_type(MEMFLAGS flags) const { 1.269 - return FLAGS_TO_MEMORY_TYPE(flags) == _type; 1.270 - } 1.271 - 1.272 - inline void inc(size_t reserved_amt, size_t committed_amt) { 1.273 - _reserved_amount += reserved_amt; 1.274 - _committed_amount += committed_amt; 1.275 - _count ++; 1.276 - } 1.277 - 1.278 - inline size_t count() const { 1.279 - return _count; 1.280 - } 1.281 - 1.282 - inline size_t reserved_amount() const { 1.283 - return _reserved_amount; 1.284 - } 1.285 - 1.286 - inline size_t committed_amount() const { 1.287 - return _committed_amount; 1.288 - } 1.289 -}; 1.290 - 1.291 - 1.292 - 1.293 -#define NUMBER_OF_MEMORY_TYPE (mt_number_of_types + 1) 1.294 - 1.295 -class BaselineReporter; 1.296 -class BaselineComparisonReporter; 1.297 - 1.298 -/* 1.299 - * This class baselines current memory snapshot. 1.300 - * A memory baseline summarizes memory usage by memory type, 1.301 - * aggregates memory usage by callsites when detail tracking 1.302 - * is on. 1.303 - */ 1.304 -class MemBaseline VALUE_OBJ_CLASS_SPEC { 1.305 - friend class BaselineReporter; 1.306 - friend class BaselineComparisonReporter; 1.307 + enum SortingOrder { 1.308 + by_address, // by memory address 1.309 + by_size, // by memory size 1.310 + by_site // by call site where the memory is allocated from 1.311 + }; 1.312 1.313 private: 1.314 - // overall summaries 1.315 - size_t _total_malloced; 1.316 - size_t _total_vm_reserved; 1.317 - size_t _total_vm_committed; 1.318 - size_t _number_of_classes; 1.319 - size_t _number_of_threads; 1.320 + // All baseline data is stored in this arena 1.321 + Arena* _arena; 1.322 1.323 - // if it has properly baselined 1.324 - bool _baselined; 1.325 + // Summary information 1.326 + MallocMemorySnapshot* _malloc_memory_snapshot; 1.327 + VirtualMemorySnapshot* _virtual_memory_snapshot; 1.328 1.329 - // we categorize memory into three categories within the memory type 1.330 - MallocMem _malloc_data[NUMBER_OF_MEMORY_TYPE]; 1.331 - VMMem _vm_data[NUMBER_OF_MEMORY_TYPE]; 1.332 - ArenaMem _arena_data[NUMBER_OF_MEMORY_TYPE]; 1.333 + size_t _class_count; 1.334 1.335 - // memory records that aggregate memory usage by callsites. 1.336 - // only available when detail tracking is on. 1.337 - MemPointerArray* _malloc_cs; 1.338 - MemPointerArray* _vm_cs; 1.339 - // virtual memory map 1.340 - MemPointerArray* _vm_map; 1.341 + // Allocation sites information 1.342 + // Malloc allocation sites 1.343 + LinkedListImpl<MallocSite, ResourceObj::ARENA> 1.344 + _malloc_sites; 1.345 1.346 - private: 1.347 - static MemType2Name MemType2NameMap[NUMBER_OF_MEMORY_TYPE]; 1.348 + // All virtual memory allocations 1.349 + LinkedListImpl<ReservedMemoryRegion, ResourceObj::ARENA> 1.350 + _virtual_memory_allocations; 1.351 1.352 - private: 1.353 - // should not use copy constructor 1.354 - MemBaseline(MemBaseline& copy) { ShouldNotReachHere(); } 1.355 + // Virtual memory allocations by allocation sites, always in by_address 1.356 + // order 1.357 + LinkedListImpl<VirtualMemoryAllocationSite, ResourceObj::ARENA> 1.358 + _virtual_memory_sites; 1.359 1.360 - // check and block at a safepoint 1.361 - static inline void check_safepoint(JavaThread* thr); 1.362 + SortingOrder _malloc_sites_order; 1.363 + SortingOrder _virtual_memory_sites_order; 1.364 + 1.365 + BaselineType _baseline_type; 1.366 1.367 public: 1.368 // create a memory baseline 1.369 - MemBaseline(); 1.370 - 1.371 - ~MemBaseline(); 1.372 - 1.373 - inline bool baselined() const { 1.374 - return _baselined; 1.375 + MemBaseline(): 1.376 + _baseline_type(Not_baselined), 1.377 + _class_count(0), 1.378 + _arena(NULL), 1.379 + _malloc_memory_snapshot(NULL), 1.380 + _virtual_memory_snapshot(NULL), 1.381 + _malloc_sites(NULL) { 1.382 } 1.383 1.384 - MemBaseline& operator=(const MemBaseline& other); 1.385 + ~MemBaseline() { 1.386 + reset(); 1.387 + if (_arena != NULL) { 1.388 + delete _arena; 1.389 + } 1.390 + } 1.391 + 1.392 + bool baseline(bool summaryOnly = true); 1.393 + 1.394 + BaselineType baseline_type() const { return _baseline_type; } 1.395 + 1.396 + MallocMemorySnapshot* malloc_memory_snapshot() const { 1.397 + return _malloc_memory_snapshot; 1.398 + } 1.399 + 1.400 + VirtualMemorySnapshot* virtual_memory_snapshot() const { 1.401 + return _virtual_memory_snapshot; 1.402 + } 1.403 + 1.404 + MallocSiteIterator malloc_sites(SortingOrder order); 1.405 + VirtualMemorySiteIterator virtual_memory_sites(SortingOrder order); 1.406 + 1.407 + // Virtual memory allocation iterator always returns in virtual memory 1.408 + // base address order. 1.409 + VirtualMemoryAllocationIterator virtual_memory_allocations() { 1.410 + assert(!_virtual_memory_allocations.is_empty(), "Not detail baseline"); 1.411 + return VirtualMemoryAllocationIterator(_virtual_memory_allocations.head()); 1.412 + } 1.413 + 1.414 + // Total reserved memory = total malloc'd memory + total reserved virtual 1.415 + // memory 1.416 + size_t total_reserved_memory() const { 1.417 + assert(baseline_type() != Not_baselined, "Not yet baselined"); 1.418 + assert(_virtual_memory_snapshot != NULL, "No virtual memory snapshot"); 1.419 + assert(_malloc_memory_snapshot != NULL, "No malloc memory snapshot"); 1.420 + size_t amount = _malloc_memory_snapshot->total() + 1.421 + _virtual_memory_snapshot->total_reserved(); 1.422 + return amount; 1.423 + } 1.424 + 1.425 + // Total committed memory = total malloc'd memory + total committed 1.426 + // virtual memory 1.427 + size_t total_committed_memory() const { 1.428 + assert(baseline_type() != Not_baselined, "Not yet baselined"); 1.429 + assert(_virtual_memory_snapshot != NULL, 1.430 + "Not a snapshot"); 1.431 + size_t amount = _malloc_memory_snapshot->total() + 1.432 + _virtual_memory_snapshot->total_committed(); 1.433 + return amount; 1.434 + } 1.435 + 1.436 + size_t total_arena_memory() const { 1.437 + assert(baseline_type() != Not_baselined, "Not yet baselined"); 1.438 + assert(_malloc_memory_snapshot != NULL, "Not yet baselined"); 1.439 + return _malloc_memory_snapshot->total_arena(); 1.440 + } 1.441 + 1.442 + size_t malloc_tracking_overhead() const { 1.443 + assert(baseline_type() != Not_baselined, "Not yet baselined"); 1.444 + return _malloc_memory_snapshot->malloc_overhead()->size(); 1.445 + } 1.446 + 1.447 + const MallocMemory* malloc_memory(MEMFLAGS flag) const { 1.448 + assert(_malloc_memory_snapshot != NULL, "Not a snapshot"); 1.449 + return _malloc_memory_snapshot->by_type(flag); 1.450 + } 1.451 + 1.452 + const VirtualMemory* virtual_memory(MEMFLAGS flag) const { 1.453 + assert(_virtual_memory_snapshot != NULL, "Not a snapshot"); 1.454 + return _virtual_memory_snapshot->by_type(flag); 1.455 + } 1.456 + 1.457 + 1.458 + size_t class_count() const { 1.459 + assert(baseline_type() != Not_baselined, "Not yet baselined"); 1.460 + return _class_count; 1.461 + } 1.462 + 1.463 + size_t thread_count() const { 1.464 + assert(baseline_type() != Not_baselined, "Not yet baselined"); 1.465 + assert(_malloc_memory_snapshot != NULL, "Baselined?"); 1.466 + return _malloc_memory_snapshot->thread_count(); 1.467 + } 1.468 1.469 // reset the baseline for reuse 1.470 - void clear(); 1.471 + void reset() { 1.472 + _baseline_type = Not_baselined; 1.473 + _malloc_memory_snapshot = NULL; 1.474 + _virtual_memory_snapshot = NULL; 1.475 + _class_count = 0; 1.476 1.477 - // baseline the snapshot 1.478 - bool baseline(MemSnapshot& snapshot, bool summary_only = true); 1.479 + _malloc_sites = NULL; 1.480 + _virtual_memory_sites = NULL; 1.481 + _virtual_memory_allocations = NULL; 1.482 1.483 - bool baseline(const MemPointerArray* malloc_records, 1.484 - const MemPointerArray* vm_records, 1.485 - bool summary_only = true); 1.486 - 1.487 - // total malloc'd memory of specified memory type 1.488 - inline size_t malloc_amount(MEMFLAGS flag) const { 1.489 - return _malloc_data[flag2index(flag)].amount(); 1.490 - } 1.491 - // number of malloc'd memory blocks of specified memory type 1.492 - inline size_t malloc_count(MEMFLAGS flag) const { 1.493 - return _malloc_data[flag2index(flag)].count(); 1.494 - } 1.495 - // total memory used by arenas of specified memory type 1.496 - inline size_t arena_amount(MEMFLAGS flag) const { 1.497 - return _arena_data[flag2index(flag)].amount(); 1.498 - } 1.499 - // number of arenas of specified memory type 1.500 - inline size_t arena_count(MEMFLAGS flag) const { 1.501 - return _arena_data[flag2index(flag)].count(); 1.502 - } 1.503 - // total reserved memory of specified memory type 1.504 - inline size_t reserved_amount(MEMFLAGS flag) const { 1.505 - return _vm_data[flag2index(flag)].reserved_amount(); 1.506 - } 1.507 - // total committed memory of specified memory type 1.508 - inline size_t committed_amount(MEMFLAGS flag) const { 1.509 - return _vm_data[flag2index(flag)].committed_amount(); 1.510 - } 1.511 - // total memory (malloc'd + mmap'd + arena) of specified 1.512 - // memory type 1.513 - inline size_t total_amount(MEMFLAGS flag) const { 1.514 - int index = flag2index(flag); 1.515 - return _malloc_data[index].amount() + 1.516 - _vm_data[index].reserved_amount() + 1.517 - _arena_data[index].amount(); 1.518 + if (_arena != NULL) { 1.519 + _arena->destruct_contents(); 1.520 + } 1.521 } 1.522 1.523 - /* overall summaries */ 1.524 + private: 1.525 + // Baseline summary information 1.526 + bool baseline_summary(); 1.527 1.528 - // total malloc'd memory in snapshot 1.529 - inline size_t total_malloc_amount() const { 1.530 - return _total_malloced; 1.531 - } 1.532 - // total mmap'd memory in snapshot 1.533 - inline size_t total_reserved_amount() const { 1.534 - return _total_vm_reserved; 1.535 - } 1.536 - // total committed memory in snapshot 1.537 - inline size_t total_committed_amount() const { 1.538 - return _total_vm_committed; 1.539 - } 1.540 - // number of loaded classes 1.541 - inline size_t number_of_classes() const { 1.542 - return _number_of_classes; 1.543 - } 1.544 - // number of running threads 1.545 - inline size_t number_of_threads() const { 1.546 - return _number_of_threads; 1.547 - } 1.548 - // lookup human readable name of a memory type 1.549 - static const char* type2name(MEMFLAGS type); 1.550 + // Baseline allocation sites (detail tracking only) 1.551 + bool baseline_allocation_sites(); 1.552 1.553 - private: 1.554 - // convert memory flag to the index to mapping table 1.555 - int flag2index(MEMFLAGS flag) const; 1.556 + // Aggregate virtual memory allocation by allocation sites 1.557 + bool aggregate_virtual_memory_allocation_sites(); 1.558 1.559 - // reset baseline values 1.560 - void reset(); 1.561 + Arena* arena() { return _arena; } 1.562 1.563 - // summarize the records in global snapshot 1.564 - bool baseline_malloc_summary(const MemPointerArray* malloc_records); 1.565 - bool baseline_vm_summary(const MemPointerArray* vm_records); 1.566 - bool baseline_malloc_details(const MemPointerArray* malloc_records); 1.567 - bool baseline_vm_details(const MemPointerArray* vm_records); 1.568 + // Sorting allocation sites in different orders 1.569 + // Sort allocation sites in size order 1.570 + void malloc_sites_to_size_order(); 1.571 + // Sort allocation sites in call site address order 1.572 + void malloc_sites_to_allocation_site_order(); 1.573 1.574 - // print a line of malloc'd memory aggregated by callsite 1.575 - void print_malloc_callsite(outputStream* st, address pc, size_t size, 1.576 - size_t count, int diff_amt, int diff_count) const; 1.577 - // print a line of mmap'd memory aggregated by callsite 1.578 - void print_vm_callsite(outputStream* st, address pc, size_t rsz, 1.579 - size_t csz, int diff_rsz, int diff_csz) const; 1.580 - 1.581 - // sorting functions for raw records 1.582 - static int malloc_sort_by_pc(const void* p1, const void* p2); 1.583 - static int malloc_sort_by_addr(const void* p1, const void* p2); 1.584 - 1.585 - private: 1.586 - // sorting functions for baselined records 1.587 - static int bl_malloc_sort_by_size(const void* p1, const void* p2); 1.588 - static int bl_vm_sort_by_size(const void* p1, const void* p2); 1.589 - static int bl_malloc_sort_by_pc(const void* p1, const void* p2); 1.590 - static int bl_vm_sort_by_pc(const void* p1, const void* p2); 1.591 + // Sort allocation sites in reserved size order 1.592 + void virtual_memory_sites_to_size_order(); 1.593 + // Sort allocation sites in call site address order 1.594 + void virtual_memory_sites_to_reservation_site_order(); 1.595 }; 1.596 1.597 +#endif // INCLUDE_NMT 1.598 1.599 #endif // SHARE_VM_SERVICES_MEM_BASELINE_HPP