--- a/hotspot/src/share/vm/services/memBaseline.hpp Tue Aug 05 14:18:44 2014 +0000
+++ b/hotspot/src/share/vm/services/memBaseline.hpp Thu Aug 07 12:18:58 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, 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
@@ -25,425 +25,205 @@
#ifndef SHARE_VM_SERVICES_MEM_BASELINE_HPP
#define SHARE_VM_SERVICES_MEM_BASELINE_HPP
+#if INCLUDE_NMT
+
#include "memory/allocation.hpp"
#include "runtime/mutex.hpp"
-#include "services/memPtr.hpp"
-#include "services/memSnapshot.hpp"
+#include "services/mallocSiteTable.hpp"
+#include "services/mallocTracker.hpp"
+#include "services/nmtCommon.hpp"
+#include "services/virtualMemoryTracker.hpp"
+#include "utilities/linkedlist.hpp"
-// compare unsigned number
-#define UNSIGNED_COMPARE(a, b) ((a > b) ? 1 : ((a == b) ? 0 : -1))
+typedef LinkedListIterator<MallocSite> MallocSiteIterator;
+typedef LinkedListIterator<VirtualMemoryAllocationSite> VirtualMemorySiteIterator;
+typedef LinkedListIterator<ReservedMemoryRegion> VirtualMemoryAllocationIterator;
/*
- * MallocCallsitePointer and VMCallsitePointer are used
- * to baseline memory blocks with their callsite information.
- * They are only available when detail tracking is turned
- * on.
+ * Baseline a memory snapshot
*/
-
-/* baselined malloc record aggregated by callsite */
-class MallocCallsitePointer : public MemPointer {
- private:
- size_t _count; // number of malloc invocation from this callsite
- size_t _amount; // total amount of memory malloc-ed from this callsite
-
+class MemBaseline VALUE_OBJ_CLASS_SPEC {
public:
- MallocCallsitePointer() {
- _count = 0;
- _amount = 0;
- }
-
- MallocCallsitePointer(address pc) : MemPointer(pc) {
- _count = 0;
- _amount = 0;
- }
+ enum BaselineThreshold {
+ SIZE_THRESHOLD = K // Only allocation size over this threshold will be baselined.
+ };
- MallocCallsitePointer& operator=(const MallocCallsitePointer& p) {
- MemPointer::operator=(p);
- _count = p.count();
- _amount = p.amount();
- return *this;
- }
+ enum BaselineType {
+ Not_baselined,
+ Summary_baselined,
+ Detail_baselined
+ };
- inline void inc(size_t size) {
- _count ++;
- _amount += size;
+ enum SortingOrder {
+ by_address, // by memory address
+ by_size, // by memory size
+ by_site // by call site where the memory is allocated from
};
- inline size_t count() const {
- return _count;
- }
+ private:
+ // All baseline data is stored in this arena
+ Arena* _arena;
+
+ // Summary information
+ MallocMemorySnapshot* _malloc_memory_snapshot;
+ VirtualMemorySnapshot* _virtual_memory_snapshot;
+
+ size_t _class_count;
- inline size_t amount() const {
- return _amount;
- }
-};
+ // Allocation sites information
+ // Malloc allocation sites
+ LinkedListImpl<MallocSite, ResourceObj::ARENA>
+ _malloc_sites;
+
+ // All virtual memory allocations
+ LinkedListImpl<ReservedMemoryRegion, ResourceObj::ARENA>
+ _virtual_memory_allocations;
-// baselined virtual memory record aggregated by callsite
-class VMCallsitePointer : public MemPointer {
- private:
- size_t _count; // number of invocation from this callsite
- size_t _reserved_amount; // total reserved amount
- size_t _committed_amount; // total committed amount
+ // Virtual memory allocations by allocation sites, always in by_address
+ // order
+ LinkedListImpl<VirtualMemoryAllocationSite, ResourceObj::ARENA>
+ _virtual_memory_sites;
+
+ SortingOrder _malloc_sites_order;
+ SortingOrder _virtual_memory_sites_order;
+
+ BaselineType _baseline_type;
public:
- VMCallsitePointer() {
- _count = 0;
- _reserved_amount = 0;
- _committed_amount = 0;
- }
-
- VMCallsitePointer(address pc) : MemPointer(pc) {
- _count = 0;
- _reserved_amount = 0;
- _committed_amount = 0;
- }
-
- VMCallsitePointer& operator=(const VMCallsitePointer& p) {
- MemPointer::operator=(p);
- _count = p.count();
- _reserved_amount = p.reserved_amount();
- _committed_amount = p.committed_amount();
- return *this;
- }
-
- inline void inc(size_t reserved, size_t committed) {
- _count ++;
- _reserved_amount += reserved;
- _committed_amount += committed;
- }
-
- inline size_t count() const {
- return _count;
- }
-
- inline size_t reserved_amount() const {
- return _reserved_amount;
+ // create a memory baseline
+ MemBaseline():
+ _baseline_type(Not_baselined),
+ _class_count(0),
+ _arena(NULL),
+ _malloc_memory_snapshot(NULL),
+ _virtual_memory_snapshot(NULL),
+ _malloc_sites(NULL) {
}
- inline size_t committed_amount() const {
- return _committed_amount;
- }
-};
-
-// maps a memory type flag to readable name
-typedef struct _memType2Name {
- MEMFLAGS _flag;
- const char* _name;
-} MemType2Name;
-
-
-// This class aggregates malloc'd records by memory type
-class MallocMem VALUE_OBJ_CLASS_SPEC {
- private:
- MEMFLAGS _type;
-
- size_t _count;
- size_t _amount;
-
- public:
- MallocMem() {
- _type = mtNone;
- _count = 0;
- _amount = 0;
+ ~MemBaseline() {
+ reset();
+ if (_arena != NULL) {
+ delete _arena;
+ }
}
- MallocMem(MEMFLAGS flags) {
- assert(HAS_VALID_MEMORY_TYPE(flags), "no type");
- _type = FLAGS_TO_MEMORY_TYPE(flags);
- _count = 0;
- _amount = 0;
- }
+ bool baseline(bool summaryOnly = true);
- inline void set_type(MEMFLAGS flag) {
- _type = flag;
- }
+ BaselineType baseline_type() const { return _baseline_type; }
- inline void clear() {
- _count = 0;
- _amount = 0;
- _type = mtNone;
+ MallocMemorySnapshot* malloc_memory_snapshot() const {
+ return _malloc_memory_snapshot;
}
- MallocMem& operator=(const MallocMem& m) {
- assert(_type == m.type(), "different type");
- _count = m.count();
- _amount = m.amount();
- return *this;
+ VirtualMemorySnapshot* virtual_memory_snapshot() const {
+ return _virtual_memory_snapshot;
}
- inline void inc(size_t amt) {
- _amount += amt;
- _count ++;
- }
+ MallocSiteIterator malloc_sites(SortingOrder order);
+ VirtualMemorySiteIterator virtual_memory_sites(SortingOrder order);
- inline void reduce(size_t amt) {
- assert(_amount >= amt, "Just check");
- _amount -= amt;
- }
-
- inline void overwrite_counter(size_t count) {
- _count = count;
+ // Virtual memory allocation iterator always returns in virtual memory
+ // base address order.
+ VirtualMemoryAllocationIterator virtual_memory_allocations() {
+ assert(!_virtual_memory_allocations.is_empty(), "Not detail baseline");
+ return VirtualMemoryAllocationIterator(_virtual_memory_allocations.head());
}
- inline MEMFLAGS type() const {
- return _type;
- }
-
- inline bool is_type(MEMFLAGS flags) const {
- return FLAGS_TO_MEMORY_TYPE(flags) == _type;
- }
-
- inline size_t count() const {
- return _count;
+ // Total reserved memory = total malloc'd memory + total reserved virtual
+ // memory
+ size_t total_reserved_memory() const {
+ assert(baseline_type() != Not_baselined, "Not yet baselined");
+ assert(_virtual_memory_snapshot != NULL, "No virtual memory snapshot");
+ assert(_malloc_memory_snapshot != NULL, "No malloc memory snapshot");
+ size_t amount = _malloc_memory_snapshot->total() +
+ _virtual_memory_snapshot->total_reserved();
+ return amount;
}
- inline size_t amount() const {
- return _amount;
- }
-};
-
-// This class records live arena's memory usage
-class ArenaMem : public MallocMem {
- public:
- ArenaMem(MEMFLAGS typeflag): MallocMem(typeflag) {
- }
- ArenaMem() { }
-};
-
-// This class aggregates virtual memory by its memory type
-class VMMem VALUE_OBJ_CLASS_SPEC {
- private:
- MEMFLAGS _type;
-
- size_t _count;
- size_t _reserved_amount;
- size_t _committed_amount;
-
- public:
- VMMem() {
- _type = mtNone;
- _count = 0;
- _reserved_amount = 0;
- _committed_amount = 0;
+ // Total committed memory = total malloc'd memory + total committed
+ // virtual memory
+ size_t total_committed_memory() const {
+ assert(baseline_type() != Not_baselined, "Not yet baselined");
+ assert(_virtual_memory_snapshot != NULL,
+ "Not a snapshot");
+ size_t amount = _malloc_memory_snapshot->total() +
+ _virtual_memory_snapshot->total_committed();
+ return amount;
}
- VMMem(MEMFLAGS flags) {
- assert(HAS_VALID_MEMORY_TYPE(flags), "no type");
- _type = FLAGS_TO_MEMORY_TYPE(flags);
- _count = 0;
- _reserved_amount = 0;
- _committed_amount = 0;
+ size_t total_arena_memory() const {
+ assert(baseline_type() != Not_baselined, "Not yet baselined");
+ assert(_malloc_memory_snapshot != NULL, "Not yet baselined");
+ return _malloc_memory_snapshot->total_arena();
}
- inline void clear() {
- _type = mtNone;
- _count = 0;
- _reserved_amount = 0;
- _committed_amount = 0;
+ size_t malloc_tracking_overhead() const {
+ assert(baseline_type() != Not_baselined, "Not yet baselined");
+ return _malloc_memory_snapshot->malloc_overhead()->size();
}
- inline void set_type(MEMFLAGS flags) {
- _type = FLAGS_TO_MEMORY_TYPE(flags);
+ const MallocMemory* malloc_memory(MEMFLAGS flag) const {
+ assert(_malloc_memory_snapshot != NULL, "Not a snapshot");
+ return _malloc_memory_snapshot->by_type(flag);
}
- VMMem& operator=(const VMMem& m) {
- assert(_type == m.type(), "different type");
-
- _count = m.count();
- _reserved_amount = m.reserved_amount();
- _committed_amount = m.committed_amount();
- return *this;
+ const VirtualMemory* virtual_memory(MEMFLAGS flag) const {
+ assert(_virtual_memory_snapshot != NULL, "Not a snapshot");
+ return _virtual_memory_snapshot->by_type(flag);
}
- inline MEMFLAGS type() const {
- return _type;
- }
-
- inline bool is_type(MEMFLAGS flags) const {
- return FLAGS_TO_MEMORY_TYPE(flags) == _type;
- }
-
- inline void inc(size_t reserved_amt, size_t committed_amt) {
- _reserved_amount += reserved_amt;
- _committed_amount += committed_amt;
- _count ++;
- }
-
- inline size_t count() const {
- return _count;
- }
-
- inline size_t reserved_amount() const {
- return _reserved_amount;
+ size_t class_count() const {
+ assert(baseline_type() != Not_baselined, "Not yet baselined");
+ return _class_count;
}
- inline size_t committed_amount() const {
- return _committed_amount;
+ size_t thread_count() const {
+ assert(baseline_type() != Not_baselined, "Not yet baselined");
+ assert(_malloc_memory_snapshot != NULL, "Baselined?");
+ return _malloc_memory_snapshot->thread_count();
}
-};
-
-
-
-#define NUMBER_OF_MEMORY_TYPE (mt_number_of_types + 1)
-
-class BaselineReporter;
-class BaselineComparisonReporter;
-
-/*
- * This class baselines current memory snapshot.
- * A memory baseline summarizes memory usage by memory type,
- * aggregates memory usage by callsites when detail tracking
- * is on.
- */
-class MemBaseline VALUE_OBJ_CLASS_SPEC {
- friend class BaselineReporter;
- friend class BaselineComparisonReporter;
-
- private:
- // overall summaries
- size_t _total_malloced;
- size_t _total_vm_reserved;
- size_t _total_vm_committed;
- size_t _number_of_classes;
- size_t _number_of_threads;
-
- // if it has properly baselined
- bool _baselined;
-
- // we categorize memory into three categories within the memory type
- MallocMem _malloc_data[NUMBER_OF_MEMORY_TYPE];
- VMMem _vm_data[NUMBER_OF_MEMORY_TYPE];
- ArenaMem _arena_data[NUMBER_OF_MEMORY_TYPE];
-
- // memory records that aggregate memory usage by callsites.
- // only available when detail tracking is on.
- MemPointerArray* _malloc_cs;
- MemPointerArray* _vm_cs;
- // virtual memory map
- MemPointerArray* _vm_map;
-
- private:
- static MemType2Name MemType2NameMap[NUMBER_OF_MEMORY_TYPE];
-
- private:
- // should not use copy constructor
- MemBaseline(MemBaseline& copy) { ShouldNotReachHere(); }
-
- // check and block at a safepoint
- static inline void check_safepoint(JavaThread* thr);
-
- public:
- // create a memory baseline
- MemBaseline();
-
- ~MemBaseline();
-
- inline bool baselined() const {
- return _baselined;
- }
-
- MemBaseline& operator=(const MemBaseline& other);
// reset the baseline for reuse
- void clear();
-
- // baseline the snapshot
- bool baseline(MemSnapshot& snapshot, bool summary_only = true);
-
- bool baseline(const MemPointerArray* malloc_records,
- const MemPointerArray* vm_records,
- bool summary_only = true);
+ void reset() {
+ _baseline_type = Not_baselined;
+ _malloc_memory_snapshot = NULL;
+ _virtual_memory_snapshot = NULL;
+ _class_count = 0;
- // total malloc'd memory of specified memory type
- inline size_t malloc_amount(MEMFLAGS flag) const {
- return _malloc_data[flag2index(flag)].amount();
- }
- // number of malloc'd memory blocks of specified memory type
- inline size_t malloc_count(MEMFLAGS flag) const {
- return _malloc_data[flag2index(flag)].count();
- }
- // total memory used by arenas of specified memory type
- inline size_t arena_amount(MEMFLAGS flag) const {
- return _arena_data[flag2index(flag)].amount();
- }
- // number of arenas of specified memory type
- inline size_t arena_count(MEMFLAGS flag) const {
- return _arena_data[flag2index(flag)].count();
- }
- // total reserved memory of specified memory type
- inline size_t reserved_amount(MEMFLAGS flag) const {
- return _vm_data[flag2index(flag)].reserved_amount();
- }
- // total committed memory of specified memory type
- inline size_t committed_amount(MEMFLAGS flag) const {
- return _vm_data[flag2index(flag)].committed_amount();
- }
- // total memory (malloc'd + mmap'd + arena) of specified
- // memory type
- inline size_t total_amount(MEMFLAGS flag) const {
- int index = flag2index(flag);
- return _malloc_data[index].amount() +
- _vm_data[index].reserved_amount() +
- _arena_data[index].amount();
+ _malloc_sites = NULL;
+ _virtual_memory_sites = NULL;
+ _virtual_memory_allocations = NULL;
+
+ if (_arena != NULL) {
+ _arena->destruct_contents();
+ }
}
- /* overall summaries */
+ private:
+ // Baseline summary information
+ bool baseline_summary();
- // total malloc'd memory in snapshot
- inline size_t total_malloc_amount() const {
- return _total_malloced;
- }
- // total mmap'd memory in snapshot
- inline size_t total_reserved_amount() const {
- return _total_vm_reserved;
- }
- // total committed memory in snapshot
- inline size_t total_committed_amount() const {
- return _total_vm_committed;
- }
- // number of loaded classes
- inline size_t number_of_classes() const {
- return _number_of_classes;
- }
- // number of running threads
- inline size_t number_of_threads() const {
- return _number_of_threads;
- }
- // lookup human readable name of a memory type
- static const char* type2name(MEMFLAGS type);
+ // Baseline allocation sites (detail tracking only)
+ bool baseline_allocation_sites();
+
+ // Aggregate virtual memory allocation by allocation sites
+ bool aggregate_virtual_memory_allocation_sites();
- private:
- // convert memory flag to the index to mapping table
- int flag2index(MEMFLAGS flag) const;
-
- // reset baseline values
- void reset();
-
- // summarize the records in global snapshot
- bool baseline_malloc_summary(const MemPointerArray* malloc_records);
- bool baseline_vm_summary(const MemPointerArray* vm_records);
- bool baseline_malloc_details(const MemPointerArray* malloc_records);
- bool baseline_vm_details(const MemPointerArray* vm_records);
+ Arena* arena() { return _arena; }
- // print a line of malloc'd memory aggregated by callsite
- void print_malloc_callsite(outputStream* st, address pc, size_t size,
- size_t count, int diff_amt, int diff_count) const;
- // print a line of mmap'd memory aggregated by callsite
- void print_vm_callsite(outputStream* st, address pc, size_t rsz,
- size_t csz, int diff_rsz, int diff_csz) const;
+ // Sorting allocation sites in different orders
+ // Sort allocation sites in size order
+ void malloc_sites_to_size_order();
+ // Sort allocation sites in call site address order
+ void malloc_sites_to_allocation_site_order();
- // sorting functions for raw records
- static int malloc_sort_by_pc(const void* p1, const void* p2);
- static int malloc_sort_by_addr(const void* p1, const void* p2);
-
- private:
- // sorting functions for baselined records
- static int bl_malloc_sort_by_size(const void* p1, const void* p2);
- static int bl_vm_sort_by_size(const void* p1, const void* p2);
- static int bl_malloc_sort_by_pc(const void* p1, const void* p2);
- static int bl_vm_sort_by_pc(const void* p1, const void* p2);
+ // Sort allocation sites in reserved size order
+ void virtual_memory_sites_to_size_order();
+ // Sort allocation sites in call site address order
+ void virtual_memory_sites_to_reservation_site_order();
};
+#endif // INCLUDE_NMT
#endif // SHARE_VM_SERVICES_MEM_BASELINE_HPP