mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 12:09:14 +00:00
8297958: NMT: Display peak values
Reviewed-by: jsjolen, sjohanss
This commit is contained in:
parent
0d2a9ee528
commit
336d230a39
@ -46,8 +46,12 @@ class MallocSite : public AllocationSite {
|
||||
|
||||
// Memory allocated from this code path
|
||||
size_t size() const { return _c.size(); }
|
||||
// Peak memory ever allocated from this code path
|
||||
size_t peak_size() const { return _c.peak_size(); }
|
||||
// The number of calls were made
|
||||
size_t count() const { return _c.count(); }
|
||||
|
||||
const MemoryCounter* counter() const { return &_c; }
|
||||
};
|
||||
|
||||
// Malloc site hashtable entry
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
#include "jvm_io.h"
|
||||
#include "logging/log.hpp"
|
||||
#include "runtime/arguments.hpp"
|
||||
#include "runtime/atomic.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/safefetch.hpp"
|
||||
#include "services/mallocHeader.inline.hpp"
|
||||
@ -42,34 +43,20 @@ size_t MallocMemorySummary::_limits_per_category[mt_number_of_types] = { 0 };
|
||||
size_t MallocMemorySummary::_total_limit = 0;
|
||||
|
||||
#ifdef ASSERT
|
||||
void MemoryCounter::update_peak_count(size_t count) {
|
||||
size_t peak_cnt = peak_count();
|
||||
while (peak_cnt < count) {
|
||||
size_t old_cnt = Atomic::cmpxchg(&_peak_count, peak_cnt, count, memory_order_relaxed);
|
||||
if (old_cnt != peak_cnt) {
|
||||
peak_cnt = old_cnt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryCounter::update_peak_size(size_t sz) {
|
||||
void MemoryCounter::update_peak(size_t size, size_t cnt) {
|
||||
size_t peak_sz = peak_size();
|
||||
while (peak_sz < sz) {
|
||||
size_t old_sz = Atomic::cmpxchg(&_peak_size, peak_sz, sz, memory_order_relaxed);
|
||||
if (old_sz != peak_sz) {
|
||||
while (peak_sz < size) {
|
||||
size_t old_sz = Atomic::cmpxchg(&_peak_size, peak_sz, size, memory_order_relaxed);
|
||||
if (old_sz == peak_sz) {
|
||||
// I won
|
||||
_peak_count = cnt;
|
||||
break;
|
||||
} else {
|
||||
peak_sz = old_sz;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t MemoryCounter::peak_count() const {
|
||||
return Atomic::load(&_peak_count);
|
||||
}
|
||||
|
||||
size_t MemoryCounter::peak_size() const {
|
||||
return Atomic::load(&_peak_size);
|
||||
}
|
||||
#endif
|
||||
#endif // ASSERT
|
||||
|
||||
// Total malloc'd memory used by arenas
|
||||
size_t MallocMemorySnapshot::total_arena() const {
|
||||
|
||||
@ -45,8 +45,13 @@ class MemoryCounter {
|
||||
volatile size_t _count;
|
||||
volatile size_t _size;
|
||||
|
||||
DEBUG_ONLY(volatile size_t _peak_count;)
|
||||
DEBUG_ONLY(volatile size_t _peak_size; )
|
||||
#ifdef ASSERT
|
||||
// Peak size and count. Note: Peak count is the count at the point
|
||||
// peak size was reached, not the absolute highest peak count.
|
||||
volatile size_t _peak_count;
|
||||
volatile size_t _peak_size;
|
||||
void update_peak(size_t size, size_t cnt);
|
||||
#endif // ASSERT
|
||||
|
||||
public:
|
||||
MemoryCounter() : _count(0), _size(0) {
|
||||
@ -58,9 +63,8 @@ class MemoryCounter {
|
||||
size_t cnt = Atomic::add(&_count, size_t(1), memory_order_relaxed);
|
||||
if (sz > 0) {
|
||||
size_t sum = Atomic::add(&_size, sz, memory_order_relaxed);
|
||||
DEBUG_ONLY(update_peak_size(sum);)
|
||||
DEBUG_ONLY(update_peak(sum, cnt);)
|
||||
}
|
||||
DEBUG_ONLY(update_peak_count(cnt);)
|
||||
}
|
||||
|
||||
inline void deallocate(size_t sz) {
|
||||
@ -76,19 +80,20 @@ class MemoryCounter {
|
||||
if (sz != 0) {
|
||||
assert(sz >= 0 || size() >= size_t(-sz), "Must be");
|
||||
size_t sum = Atomic::add(&_size, size_t(sz), memory_order_relaxed);
|
||||
DEBUG_ONLY(update_peak_size(sum);)
|
||||
DEBUG_ONLY(update_peak(sum, _count);)
|
||||
}
|
||||
}
|
||||
|
||||
inline size_t count() const { return Atomic::load(&_count); }
|
||||
inline size_t size() const { return Atomic::load(&_size); }
|
||||
|
||||
#ifdef ASSERT
|
||||
void update_peak_count(size_t cnt);
|
||||
void update_peak_size(size_t sz);
|
||||
size_t peak_count() const;
|
||||
size_t peak_size() const;
|
||||
#endif // ASSERT
|
||||
inline size_t peak_count() const {
|
||||
return DEBUG_ONLY(Atomic::load(&_peak_count)) NOT_DEBUG(0);
|
||||
}
|
||||
|
||||
inline size_t peak_size() const {
|
||||
return DEBUG_ONLY(Atomic::load(&_peak_size)) NOT_DEBUG(0);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
@ -125,12 +130,14 @@ class MallocMemory {
|
||||
}
|
||||
|
||||
inline size_t malloc_size() const { return _malloc.size(); }
|
||||
inline size_t malloc_peak_size() const { return _malloc.peak_size(); }
|
||||
inline size_t malloc_count() const { return _malloc.count();}
|
||||
inline size_t arena_size() const { return _arena.size(); }
|
||||
inline size_t arena_peak_size() const { return _arena.peak_size(); }
|
||||
inline size_t arena_count() const { return _arena.count(); }
|
||||
|
||||
DEBUG_ONLY(inline const MemoryCounter& malloc_counter() const { return _malloc; })
|
||||
DEBUG_ONLY(inline const MemoryCounter& arena_counter() const { return _arena; })
|
||||
const MemoryCounter* malloc_counter() const { return &_malloc; }
|
||||
const MemoryCounter* arena_counter() const { return &_arena; }
|
||||
};
|
||||
|
||||
class MallocMemorySummary;
|
||||
|
||||
@ -45,11 +45,14 @@ void MemReporterBase::print_total(size_t reserved, size_t committed) const {
|
||||
amount_in_current_scale(reserved), scale, amount_in_current_scale(committed), scale);
|
||||
}
|
||||
|
||||
void MemReporterBase::print_malloc(size_t amount, size_t count, MEMFLAGS flag) const {
|
||||
void MemReporterBase::print_malloc(const MemoryCounter* c, MEMFLAGS flag) const {
|
||||
const char* scale = current_scale();
|
||||
outputStream* out = output();
|
||||
const char* alloc_type = (flag == mtThreadStack) ? "" : "malloc=";
|
||||
|
||||
const size_t amount = c->size();
|
||||
const size_t count = c->count();
|
||||
|
||||
if (flag != mtNone) {
|
||||
out->print("(%s" SIZE_FORMAT "%s type=%s", alloc_type,
|
||||
amount_in_current_scale(amount), scale, NMTUtil::flag_to_name(flag));
|
||||
@ -58,11 +61,21 @@ void MemReporterBase::print_malloc(size_t amount, size_t count, MEMFLAGS flag) c
|
||||
amount_in_current_scale(amount), scale);
|
||||
}
|
||||
|
||||
// blends out mtChunk count number
|
||||
if (count > 0) {
|
||||
out->print(" #" SIZE_FORMAT "", count);
|
||||
}
|
||||
|
||||
out->print(")");
|
||||
|
||||
size_t pk_amount = c->peak_size();
|
||||
if (pk_amount == amount) {
|
||||
out->print_raw(" (at peak)");
|
||||
} else if (pk_amount > amount) {
|
||||
size_t pk_count = c->peak_count();
|
||||
out->print(" (peak=" SIZE_FORMAT "%s #" SIZE_FORMAT ")",
|
||||
amount_in_current_scale(pk_amount), scale, pk_count);
|
||||
}
|
||||
}
|
||||
|
||||
void MemReporterBase::print_virtual_memory(size_t reserved, size_t committed) const {
|
||||
@ -71,9 +84,9 @@ void MemReporterBase::print_virtual_memory(size_t reserved, size_t committed) co
|
||||
amount_in_current_scale(reserved), scale, amount_in_current_scale(committed), scale);
|
||||
}
|
||||
|
||||
void MemReporterBase::print_malloc_line(size_t amount, size_t count) const {
|
||||
void MemReporterBase::print_malloc_line(const MemoryCounter* c) const {
|
||||
output()->print("%28s", " ");
|
||||
print_malloc(amount, count);
|
||||
print_malloc(c);
|
||||
output()->print_cr(" ");
|
||||
}
|
||||
|
||||
@ -83,10 +96,26 @@ void MemReporterBase::print_virtual_memory_line(size_t reserved, size_t committe
|
||||
output()->print_cr(" ");
|
||||
}
|
||||
|
||||
void MemReporterBase::print_arena_line(size_t amount, size_t count) const {
|
||||
void MemReporterBase::print_arena_line(const MemoryCounter* c) const {
|
||||
const char* scale = current_scale();
|
||||
output()->print_cr("%27s (arena=" SIZE_FORMAT "%s #" SIZE_FORMAT ")", " ",
|
||||
outputStream* out = output();
|
||||
|
||||
const size_t amount = c->size();
|
||||
const size_t count = c->count();
|
||||
|
||||
out->print("%27s (arena=" SIZE_FORMAT "%s #" SIZE_FORMAT ")", "",
|
||||
amount_in_current_scale(amount), scale, count);
|
||||
|
||||
size_t pk_amount = c->peak_size();
|
||||
if (pk_amount == amount) {
|
||||
out->print_raw(" (at peak)");
|
||||
} else if (pk_amount > amount) {
|
||||
size_t pk_count = c->peak_count();
|
||||
out->print(" (peak=" SIZE_FORMAT "%s #" SIZE_FORMAT ")",
|
||||
amount_in_current_scale(pk_amount), scale, pk_count);
|
||||
}
|
||||
|
||||
out->cr();
|
||||
}
|
||||
|
||||
void MemReporterBase::print_virtual_memory_region(const char* type, address base, size_t size) const {
|
||||
@ -195,18 +224,18 @@ void MemSummaryReporter::report_summary_of_type(MEMFLAGS flag,
|
||||
}
|
||||
|
||||
// report malloc'd memory
|
||||
if (amount_in_current_scale(malloc_memory->malloc_size()) > 0) {
|
||||
// We don't know how many arena chunks are in used, so don't report the count
|
||||
size_t count = (flag == mtChunk) ? 0 : malloc_memory->malloc_count();
|
||||
print_malloc_line(malloc_memory->malloc_size(), count);
|
||||
if (amount_in_current_scale(malloc_memory->malloc_size()) > 0
|
||||
DEBUG_ONLY(|| amount_in_current_scale(malloc_memory->malloc_peak_size()) > 0)) {
|
||||
print_malloc_line(malloc_memory->malloc_counter());
|
||||
}
|
||||
|
||||
if (amount_in_current_scale(virtual_memory->reserved()) > 0) {
|
||||
print_virtual_memory_line(virtual_memory->reserved(), virtual_memory->committed());
|
||||
}
|
||||
|
||||
if (amount_in_current_scale(malloc_memory->arena_size()) > 0) {
|
||||
print_arena_line(malloc_memory->arena_size(), malloc_memory->arena_count());
|
||||
if (amount_in_current_scale(malloc_memory->arena_size()) > 0
|
||||
DEBUG_ONLY(|| amount_in_current_scale(malloc_memory->arena_peak_size()) > 0)) {
|
||||
print_arena_line(malloc_memory->arena_counter());
|
||||
}
|
||||
|
||||
if (flag == mtNMT &&
|
||||
@ -271,12 +300,9 @@ int MemDetailReporter::report_malloc_sites() {
|
||||
const MallocSite* malloc_site;
|
||||
int num_omitted = 0;
|
||||
while ((malloc_site = malloc_itr.next()) != NULL) {
|
||||
// Don't report free sites; does not count toward omitted count.
|
||||
if (malloc_site->size() == 0) {
|
||||
continue;
|
||||
}
|
||||
// Don't report if site has allocated less than one unit of whatever our scale is
|
||||
if (scale() > 1 && amount_in_current_scale(malloc_site->size()) == 0) {
|
||||
// Don't report if site has never allocated less than one unit of whatever our scale is
|
||||
if (scale() > 1 && amount_in_current_scale(malloc_site->size()) == 0
|
||||
DEBUG_ONLY(&& amount_in_current_scale(malloc_site->peak_size()) == 0)) {
|
||||
num_omitted ++;
|
||||
continue;
|
||||
}
|
||||
@ -286,7 +312,7 @@ int MemDetailReporter::report_malloc_sites() {
|
||||
MEMFLAGS flag = malloc_site->flag();
|
||||
assert(NMTUtil::flag_is_valid(flag) && flag != mtNone,
|
||||
"Must have a valid memory type");
|
||||
print_malloc(malloc_site->size(), malloc_site->count(),flag);
|
||||
print_malloc(malloc_site->counter(), flag);
|
||||
out->print_cr("\n");
|
||||
}
|
||||
return num_omitted;
|
||||
|
||||
@ -80,12 +80,12 @@ class MemReporterBase : public StackObj {
|
||||
|
||||
// Print summary total, malloc and virtual memory
|
||||
void print_total(size_t reserved, size_t committed) const;
|
||||
void print_malloc(size_t amount, size_t count, MEMFLAGS flag = mtNone) const;
|
||||
void print_malloc(const MemoryCounter* c, MEMFLAGS flag = mtNone) const;
|
||||
void print_virtual_memory(size_t reserved, size_t committed) const;
|
||||
|
||||
void print_malloc_line(size_t amount, size_t count) const;
|
||||
void print_malloc_line(const MemoryCounter* c) const;
|
||||
void print_virtual_memory_line(size_t reserved, size_t committed) const;
|
||||
void print_arena_line(size_t amount, size_t count) const;
|
||||
void print_arena_line(const MemoryCounter* c) const;
|
||||
|
||||
void print_virtual_memory_region(const char* type, address base, size_t size) const;
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user