src/share/vm/services/memBaseline.hpp

Tue, 08 Aug 2017 15:57:29 +0800

author
aoqi
date
Tue, 08 Aug 2017 15:57:29 +0800
changeset 6876
710a3c8b516e
parent 4980
fbca7eaeac2e
parent 0
f90c822e73f8
child 7535
7ae4e26cb1e0
permissions
-rw-r--r--

merge

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation.
aoqi@0 8 *
aoqi@0 9 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 12 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 13 * accompanied this code).
aoqi@0 14 *
aoqi@0 15 * You should have received a copy of the GNU General Public License version
aoqi@0 16 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 18 *
aoqi@0 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 20 * or visit www.oracle.com if you need additional information or have any
aoqi@0 21 * questions.
aoqi@0 22 *
aoqi@0 23 */
aoqi@0 24
aoqi@0 25 #ifndef SHARE_VM_SERVICES_MEM_BASELINE_HPP
aoqi@0 26 #define SHARE_VM_SERVICES_MEM_BASELINE_HPP
aoqi@0 27
aoqi@0 28 #include "memory/allocation.hpp"
aoqi@0 29 #include "runtime/mutex.hpp"
aoqi@0 30 #include "services/memPtr.hpp"
aoqi@0 31 #include "services/memSnapshot.hpp"
aoqi@0 32
aoqi@0 33 // compare unsigned number
aoqi@0 34 #define UNSIGNED_COMPARE(a, b) ((a > b) ? 1 : ((a == b) ? 0 : -1))
aoqi@0 35
aoqi@0 36 /*
aoqi@0 37 * MallocCallsitePointer and VMCallsitePointer are used
aoqi@0 38 * to baseline memory blocks with their callsite information.
aoqi@0 39 * They are only available when detail tracking is turned
aoqi@0 40 * on.
aoqi@0 41 */
aoqi@0 42
aoqi@0 43 /* baselined malloc record aggregated by callsite */
aoqi@0 44 class MallocCallsitePointer : public MemPointer {
aoqi@0 45 private:
aoqi@0 46 size_t _count; // number of malloc invocation from this callsite
aoqi@0 47 size_t _amount; // total amount of memory malloc-ed from this callsite
aoqi@0 48
aoqi@0 49 public:
aoqi@0 50 MallocCallsitePointer() {
aoqi@0 51 _count = 0;
aoqi@0 52 _amount = 0;
aoqi@0 53 }
aoqi@0 54
aoqi@0 55 MallocCallsitePointer(address pc) : MemPointer(pc) {
aoqi@0 56 _count = 0;
aoqi@0 57 _amount = 0;
aoqi@0 58 }
aoqi@0 59
aoqi@0 60 MallocCallsitePointer& operator=(const MallocCallsitePointer& p) {
aoqi@0 61 MemPointer::operator=(p);
aoqi@0 62 _count = p.count();
aoqi@0 63 _amount = p.amount();
aoqi@0 64 return *this;
aoqi@0 65 }
aoqi@0 66
aoqi@0 67 inline void inc(size_t size) {
aoqi@0 68 _count ++;
aoqi@0 69 _amount += size;
aoqi@0 70 };
aoqi@0 71
aoqi@0 72 inline size_t count() const {
aoqi@0 73 return _count;
aoqi@0 74 }
aoqi@0 75
aoqi@0 76 inline size_t amount() const {
aoqi@0 77 return _amount;
aoqi@0 78 }
aoqi@0 79 };
aoqi@0 80
aoqi@0 81 // baselined virtual memory record aggregated by callsite
aoqi@0 82 class VMCallsitePointer : public MemPointer {
aoqi@0 83 private:
aoqi@0 84 size_t _count; // number of invocation from this callsite
aoqi@0 85 size_t _reserved_amount; // total reserved amount
aoqi@0 86 size_t _committed_amount; // total committed amount
aoqi@0 87
aoqi@0 88 public:
aoqi@0 89 VMCallsitePointer() {
aoqi@0 90 _count = 0;
aoqi@0 91 _reserved_amount = 0;
aoqi@0 92 _committed_amount = 0;
aoqi@0 93 }
aoqi@0 94
aoqi@0 95 VMCallsitePointer(address pc) : MemPointer(pc) {
aoqi@0 96 _count = 0;
aoqi@0 97 _reserved_amount = 0;
aoqi@0 98 _committed_amount = 0;
aoqi@0 99 }
aoqi@0 100
aoqi@0 101 VMCallsitePointer& operator=(const VMCallsitePointer& p) {
aoqi@0 102 MemPointer::operator=(p);
aoqi@0 103 _count = p.count();
aoqi@0 104 _reserved_amount = p.reserved_amount();
aoqi@0 105 _committed_amount = p.committed_amount();
aoqi@0 106 return *this;
aoqi@0 107 }
aoqi@0 108
aoqi@0 109 inline void inc(size_t reserved, size_t committed) {
aoqi@0 110 _count ++;
aoqi@0 111 _reserved_amount += reserved;
aoqi@0 112 _committed_amount += committed;
aoqi@0 113 }
aoqi@0 114
aoqi@0 115 inline size_t count() const {
aoqi@0 116 return _count;
aoqi@0 117 }
aoqi@0 118
aoqi@0 119 inline size_t reserved_amount() const {
aoqi@0 120 return _reserved_amount;
aoqi@0 121 }
aoqi@0 122
aoqi@0 123 inline size_t committed_amount() const {
aoqi@0 124 return _committed_amount;
aoqi@0 125 }
aoqi@0 126 };
aoqi@0 127
aoqi@0 128 // maps a memory type flag to readable name
aoqi@0 129 typedef struct _memType2Name {
aoqi@0 130 MEMFLAGS _flag;
aoqi@0 131 const char* _name;
aoqi@0 132 } MemType2Name;
aoqi@0 133
aoqi@0 134
aoqi@0 135 // This class aggregates malloc'd records by memory type
aoqi@0 136 class MallocMem VALUE_OBJ_CLASS_SPEC {
aoqi@0 137 private:
aoqi@0 138 MEMFLAGS _type;
aoqi@0 139
aoqi@0 140 size_t _count;
aoqi@0 141 size_t _amount;
aoqi@0 142
aoqi@0 143 public:
aoqi@0 144 MallocMem() {
aoqi@0 145 _type = mtNone;
aoqi@0 146 _count = 0;
aoqi@0 147 _amount = 0;
aoqi@0 148 }
aoqi@0 149
aoqi@0 150 MallocMem(MEMFLAGS flags) {
aoqi@0 151 assert(HAS_VALID_MEMORY_TYPE(flags), "no type");
aoqi@0 152 _type = FLAGS_TO_MEMORY_TYPE(flags);
aoqi@0 153 _count = 0;
aoqi@0 154 _amount = 0;
aoqi@0 155 }
aoqi@0 156
aoqi@0 157 inline void set_type(MEMFLAGS flag) {
aoqi@0 158 _type = flag;
aoqi@0 159 }
aoqi@0 160
aoqi@0 161 inline void clear() {
aoqi@0 162 _count = 0;
aoqi@0 163 _amount = 0;
aoqi@0 164 _type = mtNone;
aoqi@0 165 }
aoqi@0 166
aoqi@0 167 MallocMem& operator=(const MallocMem& m) {
aoqi@0 168 assert(_type == m.type(), "different type");
aoqi@0 169 _count = m.count();
aoqi@0 170 _amount = m.amount();
aoqi@0 171 return *this;
aoqi@0 172 }
aoqi@0 173
aoqi@0 174 inline void inc(size_t amt) {
aoqi@0 175 _amount += amt;
aoqi@0 176 _count ++;
aoqi@0 177 }
aoqi@0 178
aoqi@0 179 inline void reduce(size_t amt) {
aoqi@0 180 assert(_amount >= amt, "Just check");
aoqi@0 181 _amount -= amt;
aoqi@0 182 }
aoqi@0 183
aoqi@0 184 inline void overwrite_counter(size_t count) {
aoqi@0 185 _count = count;
aoqi@0 186 }
aoqi@0 187
aoqi@0 188 inline MEMFLAGS type() const {
aoqi@0 189 return _type;
aoqi@0 190 }
aoqi@0 191
aoqi@0 192 inline bool is_type(MEMFLAGS flags) const {
aoqi@0 193 return FLAGS_TO_MEMORY_TYPE(flags) == _type;
aoqi@0 194 }
aoqi@0 195
aoqi@0 196 inline size_t count() const {
aoqi@0 197 return _count;
aoqi@0 198 }
aoqi@0 199
aoqi@0 200 inline size_t amount() const {
aoqi@0 201 return _amount;
aoqi@0 202 }
aoqi@0 203 };
aoqi@0 204
aoqi@0 205 // This class records live arena's memory usage
aoqi@0 206 class ArenaMem : public MallocMem {
aoqi@0 207 public:
aoqi@0 208 ArenaMem(MEMFLAGS typeflag): MallocMem(typeflag) {
aoqi@0 209 }
aoqi@0 210 ArenaMem() { }
aoqi@0 211 };
aoqi@0 212
aoqi@0 213 // This class aggregates virtual memory by its memory type
aoqi@0 214 class VMMem VALUE_OBJ_CLASS_SPEC {
aoqi@0 215 private:
aoqi@0 216 MEMFLAGS _type;
aoqi@0 217
aoqi@0 218 size_t _count;
aoqi@0 219 size_t _reserved_amount;
aoqi@0 220 size_t _committed_amount;
aoqi@0 221
aoqi@0 222 public:
aoqi@0 223 VMMem() {
aoqi@0 224 _type = mtNone;
aoqi@0 225 _count = 0;
aoqi@0 226 _reserved_amount = 0;
aoqi@0 227 _committed_amount = 0;
aoqi@0 228 }
aoqi@0 229
aoqi@0 230 VMMem(MEMFLAGS flags) {
aoqi@0 231 assert(HAS_VALID_MEMORY_TYPE(flags), "no type");
aoqi@0 232 _type = FLAGS_TO_MEMORY_TYPE(flags);
aoqi@0 233 _count = 0;
aoqi@0 234 _reserved_amount = 0;
aoqi@0 235 _committed_amount = 0;
aoqi@0 236 }
aoqi@0 237
aoqi@0 238 inline void clear() {
aoqi@0 239 _type = mtNone;
aoqi@0 240 _count = 0;
aoqi@0 241 _reserved_amount = 0;
aoqi@0 242 _committed_amount = 0;
aoqi@0 243 }
aoqi@0 244
aoqi@0 245 inline void set_type(MEMFLAGS flags) {
aoqi@0 246 _type = FLAGS_TO_MEMORY_TYPE(flags);
aoqi@0 247 }
aoqi@0 248
aoqi@0 249 VMMem& operator=(const VMMem& m) {
aoqi@0 250 assert(_type == m.type(), "different type");
aoqi@0 251
aoqi@0 252 _count = m.count();
aoqi@0 253 _reserved_amount = m.reserved_amount();
aoqi@0 254 _committed_amount = m.committed_amount();
aoqi@0 255 return *this;
aoqi@0 256 }
aoqi@0 257
aoqi@0 258
aoqi@0 259 inline MEMFLAGS type() const {
aoqi@0 260 return _type;
aoqi@0 261 }
aoqi@0 262
aoqi@0 263 inline bool is_type(MEMFLAGS flags) const {
aoqi@0 264 return FLAGS_TO_MEMORY_TYPE(flags) == _type;
aoqi@0 265 }
aoqi@0 266
aoqi@0 267 inline void inc(size_t reserved_amt, size_t committed_amt) {
aoqi@0 268 _reserved_amount += reserved_amt;
aoqi@0 269 _committed_amount += committed_amt;
aoqi@0 270 _count ++;
aoqi@0 271 }
aoqi@0 272
aoqi@0 273 inline size_t count() const {
aoqi@0 274 return _count;
aoqi@0 275 }
aoqi@0 276
aoqi@0 277 inline size_t reserved_amount() const {
aoqi@0 278 return _reserved_amount;
aoqi@0 279 }
aoqi@0 280
aoqi@0 281 inline size_t committed_amount() const {
aoqi@0 282 return _committed_amount;
aoqi@0 283 }
aoqi@0 284 };
aoqi@0 285
aoqi@0 286
aoqi@0 287
aoqi@0 288 #define NUMBER_OF_MEMORY_TYPE (mt_number_of_types + 1)
aoqi@0 289
aoqi@0 290 class BaselineReporter;
aoqi@0 291 class BaselineComparisonReporter;
aoqi@0 292
aoqi@0 293 /*
aoqi@0 294 * This class baselines current memory snapshot.
aoqi@0 295 * A memory baseline summarizes memory usage by memory type,
aoqi@0 296 * aggregates memory usage by callsites when detail tracking
aoqi@0 297 * is on.
aoqi@0 298 */
aoqi@0 299 class MemBaseline VALUE_OBJ_CLASS_SPEC {
aoqi@0 300 friend class BaselineReporter;
aoqi@0 301 friend class BaselineComparisonReporter;
aoqi@0 302
aoqi@0 303 private:
aoqi@0 304 // overall summaries
aoqi@0 305 size_t _total_malloced;
aoqi@0 306 size_t _total_vm_reserved;
aoqi@0 307 size_t _total_vm_committed;
aoqi@0 308 size_t _number_of_classes;
aoqi@0 309 size_t _number_of_threads;
aoqi@0 310
aoqi@0 311 // if it has properly baselined
aoqi@0 312 bool _baselined;
aoqi@0 313
aoqi@0 314 // we categorize memory into three categories within the memory type
aoqi@0 315 MallocMem _malloc_data[NUMBER_OF_MEMORY_TYPE];
aoqi@0 316 VMMem _vm_data[NUMBER_OF_MEMORY_TYPE];
aoqi@0 317 ArenaMem _arena_data[NUMBER_OF_MEMORY_TYPE];
aoqi@0 318
aoqi@0 319 // memory records that aggregate memory usage by callsites.
aoqi@0 320 // only available when detail tracking is on.
aoqi@0 321 MemPointerArray* _malloc_cs;
aoqi@0 322 MemPointerArray* _vm_cs;
aoqi@0 323 // virtual memory map
aoqi@0 324 MemPointerArray* _vm_map;
aoqi@0 325
aoqi@0 326 private:
aoqi@0 327 static MemType2Name MemType2NameMap[NUMBER_OF_MEMORY_TYPE];
aoqi@0 328
aoqi@0 329 private:
aoqi@0 330 // should not use copy constructor
aoqi@0 331 MemBaseline(MemBaseline& copy) { ShouldNotReachHere(); }
aoqi@0 332
aoqi@0 333 // check and block at a safepoint
aoqi@0 334 static inline void check_safepoint(JavaThread* thr);
aoqi@0 335
aoqi@0 336 public:
aoqi@0 337 // create a memory baseline
aoqi@0 338 MemBaseline();
aoqi@0 339
aoqi@0 340 ~MemBaseline();
aoqi@0 341
aoqi@0 342 inline bool baselined() const {
aoqi@0 343 return _baselined;
aoqi@0 344 }
aoqi@0 345
aoqi@0 346 MemBaseline& operator=(const MemBaseline& other);
aoqi@0 347
aoqi@0 348 // reset the baseline for reuse
aoqi@0 349 void clear();
aoqi@0 350
aoqi@0 351 // baseline the snapshot
aoqi@0 352 bool baseline(MemSnapshot& snapshot, bool summary_only = true);
aoqi@0 353
aoqi@0 354 bool baseline(const MemPointerArray* malloc_records,
aoqi@0 355 const MemPointerArray* vm_records,
aoqi@0 356 bool summary_only = true);
aoqi@0 357
aoqi@0 358 // total malloc'd memory of specified memory type
aoqi@0 359 inline size_t malloc_amount(MEMFLAGS flag) const {
aoqi@0 360 return _malloc_data[flag2index(flag)].amount();
aoqi@0 361 }
aoqi@0 362 // number of malloc'd memory blocks of specified memory type
aoqi@0 363 inline size_t malloc_count(MEMFLAGS flag) const {
aoqi@0 364 return _malloc_data[flag2index(flag)].count();
aoqi@0 365 }
aoqi@0 366 // total memory used by arenas of specified memory type
aoqi@0 367 inline size_t arena_amount(MEMFLAGS flag) const {
aoqi@0 368 return _arena_data[flag2index(flag)].amount();
aoqi@0 369 }
aoqi@0 370 // number of arenas of specified memory type
aoqi@0 371 inline size_t arena_count(MEMFLAGS flag) const {
aoqi@0 372 return _arena_data[flag2index(flag)].count();
aoqi@0 373 }
aoqi@0 374 // total reserved memory of specified memory type
aoqi@0 375 inline size_t reserved_amount(MEMFLAGS flag) const {
aoqi@0 376 return _vm_data[flag2index(flag)].reserved_amount();
aoqi@0 377 }
aoqi@0 378 // total committed memory of specified memory type
aoqi@0 379 inline size_t committed_amount(MEMFLAGS flag) const {
aoqi@0 380 return _vm_data[flag2index(flag)].committed_amount();
aoqi@0 381 }
aoqi@0 382 // total memory (malloc'd + mmap'd + arena) of specified
aoqi@0 383 // memory type
aoqi@0 384 inline size_t total_amount(MEMFLAGS flag) const {
aoqi@0 385 int index = flag2index(flag);
aoqi@0 386 return _malloc_data[index].amount() +
aoqi@0 387 _vm_data[index].reserved_amount() +
aoqi@0 388 _arena_data[index].amount();
aoqi@0 389 }
aoqi@0 390
aoqi@0 391 /* overall summaries */
aoqi@0 392
aoqi@0 393 // total malloc'd memory in snapshot
aoqi@0 394 inline size_t total_malloc_amount() const {
aoqi@0 395 return _total_malloced;
aoqi@0 396 }
aoqi@0 397 // total mmap'd memory in snapshot
aoqi@0 398 inline size_t total_reserved_amount() const {
aoqi@0 399 return _total_vm_reserved;
aoqi@0 400 }
aoqi@0 401 // total committed memory in snapshot
aoqi@0 402 inline size_t total_committed_amount() const {
aoqi@0 403 return _total_vm_committed;
aoqi@0 404 }
aoqi@0 405 // number of loaded classes
aoqi@0 406 inline size_t number_of_classes() const {
aoqi@0 407 return _number_of_classes;
aoqi@0 408 }
aoqi@0 409 // number of running threads
aoqi@0 410 inline size_t number_of_threads() const {
aoqi@0 411 return _number_of_threads;
aoqi@0 412 }
aoqi@0 413 // lookup human readable name of a memory type
aoqi@0 414 static const char* type2name(MEMFLAGS type);
aoqi@0 415
aoqi@0 416 private:
aoqi@0 417 // convert memory flag to the index to mapping table
aoqi@0 418 int flag2index(MEMFLAGS flag) const;
aoqi@0 419
aoqi@0 420 // reset baseline values
aoqi@0 421 void reset();
aoqi@0 422
aoqi@0 423 // summarize the records in global snapshot
aoqi@0 424 bool baseline_malloc_summary(const MemPointerArray* malloc_records);
aoqi@0 425 bool baseline_vm_summary(const MemPointerArray* vm_records);
aoqi@0 426 bool baseline_malloc_details(const MemPointerArray* malloc_records);
aoqi@0 427 bool baseline_vm_details(const MemPointerArray* vm_records);
aoqi@0 428
aoqi@0 429 // print a line of malloc'd memory aggregated by callsite
aoqi@0 430 void print_malloc_callsite(outputStream* st, address pc, size_t size,
aoqi@0 431 size_t count, int diff_amt, int diff_count) const;
aoqi@0 432 // print a line of mmap'd memory aggregated by callsite
aoqi@0 433 void print_vm_callsite(outputStream* st, address pc, size_t rsz,
aoqi@0 434 size_t csz, int diff_rsz, int diff_csz) const;
aoqi@0 435
aoqi@0 436 // sorting functions for raw records
aoqi@0 437 static int malloc_sort_by_pc(const void* p1, const void* p2);
aoqi@0 438 static int malloc_sort_by_addr(const void* p1, const void* p2);
aoqi@0 439
aoqi@0 440 private:
aoqi@0 441 // sorting functions for baselined records
aoqi@0 442 static int bl_malloc_sort_by_size(const void* p1, const void* p2);
aoqi@0 443 static int bl_vm_sort_by_size(const void* p1, const void* p2);
aoqi@0 444 static int bl_malloc_sort_by_pc(const void* p1, const void* p2);
aoqi@0 445 static int bl_vm_sort_by_pc(const void* p1, const void* p2);
aoqi@0 446 };
aoqi@0 447
aoqi@0 448
aoqi@0 449 #endif // SHARE_VM_SERVICES_MEM_BASELINE_HPP

mercurial