Add merged arena stats printing.
Add the "m" and "a" opts flags for malloc_stats_print().
This commit is contained in:
parent
3363a841ca
commit
b34e8684ec
@ -194,7 +194,11 @@ during execution can be omitted by specifying
|
|||||||
as a character within the
|
as a character within the
|
||||||
.Fa opts
|
.Fa opts
|
||||||
string.
|
string.
|
||||||
@roff_stats@Similarly,
|
@roff_stats@.Dq m
|
||||||
|
@roff_stats@and
|
||||||
|
@roff_stats@.Dq a
|
||||||
|
@roff_stats@can be specified to omit merged arena and per arena statistics,
|
||||||
|
@roff_stats@respectively.
|
||||||
@roff_stats@.Dq b
|
@roff_stats@.Dq b
|
||||||
@roff_stats@and
|
@roff_stats@and
|
||||||
@roff_stats@.Dq l
|
@roff_stats@.Dq l
|
||||||
|
@ -405,6 +405,13 @@ void arena_dalloc_bin(arena_t *arena, arena_chunk_t *chunk, void *ptr,
|
|||||||
arena_chunk_map_t *mapelm);
|
arena_chunk_map_t *mapelm);
|
||||||
void arena_dalloc_large(arena_t *arena, arena_chunk_t *chunk, void *ptr);
|
void arena_dalloc_large(arena_t *arena, arena_chunk_t *chunk, void *ptr);
|
||||||
#ifdef JEMALLOC_STATS
|
#ifdef JEMALLOC_STATS
|
||||||
|
void arena_stats_merge(arena_t *arena, size_t *nactive, size_t *ndirty,
|
||||||
|
arena_stats_t *astats, malloc_bin_stats_t *bstats,
|
||||||
|
malloc_large_stats_t *lstats);
|
||||||
|
void arena_stats_mprint(arena_t *arena, size_t nactive, size_t ndirty,
|
||||||
|
const arena_stats_t *astats, const malloc_bin_stats_t *bstats,
|
||||||
|
const malloc_large_stats_t *lstats, bool bins, bool large,
|
||||||
|
void (*write4)(const char *, const char *, const char *, const char *));
|
||||||
void arena_stats_print(arena_t *arena, bool bins, bool large,
|
void arena_stats_print(arena_t *arena, bool bins, bool large,
|
||||||
void (*write4)(const char *, const char *, const char *, const char *));
|
void (*write4)(const char *, const char *, const char *, const char *));
|
||||||
#endif
|
#endif
|
||||||
|
@ -172,6 +172,16 @@ static void *arena_malloc_large(arena_t *arena, size_t size, bool zero);
|
|||||||
static bool arena_is_large(const void *ptr);
|
static bool arena_is_large(const void *ptr);
|
||||||
static void arena_dalloc_bin_run(arena_t *arena, arena_chunk_t *chunk,
|
static void arena_dalloc_bin_run(arena_t *arena, arena_chunk_t *chunk,
|
||||||
arena_run_t *run, arena_bin_t *bin);
|
arena_run_t *run, arena_bin_t *bin);
|
||||||
|
#ifdef JEMALLOC_STATS
|
||||||
|
static void arena_stats_aprint(size_t nactive, size_t ndirty,
|
||||||
|
const arena_stats_t *astats,
|
||||||
|
void (*write4)(const char *, const char *, const char *, const char *));
|
||||||
|
static void arena_stats_bprint(arena_t *arena,
|
||||||
|
const malloc_bin_stats_t *bstats,
|
||||||
|
void (*write4)(const char *, const char *, const char *, const char *));
|
||||||
|
static void arena_stats_lprint(const malloc_large_stats_t *lstats,
|
||||||
|
void (*write4)(const char *, const char *, const char *, const char *));
|
||||||
|
#endif
|
||||||
static void arena_ralloc_large_shrink(arena_t *arena, arena_chunk_t *chunk,
|
static void arena_ralloc_large_shrink(arena_t *arena, arena_chunk_t *chunk,
|
||||||
void *ptr, size_t size, size_t oldsize);
|
void *ptr, size_t size, size_t oldsize);
|
||||||
static bool arena_ralloc_large_grow(arena_t *arena, arena_chunk_t *chunk,
|
static bool arena_ralloc_large_grow(arena_t *arena, arena_chunk_t *chunk,
|
||||||
@ -1548,40 +1558,88 @@ arena_dalloc_bin(arena_t *arena, arena_chunk_t *chunk, void *ptr,
|
|||||||
|
|
||||||
#ifdef JEMALLOC_STATS
|
#ifdef JEMALLOC_STATS
|
||||||
void
|
void
|
||||||
arena_stats_print(arena_t *arena, bool bins, bool large,
|
arena_stats_merge(arena_t *arena, size_t *nactive, size_t *ndirty,
|
||||||
|
arena_stats_t *astats, malloc_bin_stats_t *bstats,
|
||||||
|
malloc_large_stats_t *lstats)
|
||||||
|
{
|
||||||
|
unsigned i, nlclasses;
|
||||||
|
|
||||||
|
*nactive += arena->nactive;
|
||||||
|
*ndirty += arena->ndirty;
|
||||||
|
|
||||||
|
astats->npurge += arena->stats.npurge;
|
||||||
|
astats->nmadvise += arena->stats.nmadvise;
|
||||||
|
astats->purged += arena->stats.purged;
|
||||||
|
astats->allocated_small += arena->stats.allocated_small;
|
||||||
|
astats->nmalloc_small += arena->stats.nmalloc_small;
|
||||||
|
astats->ndalloc_small += arena->stats.ndalloc_small;
|
||||||
|
astats->allocated_medium += arena->stats.allocated_medium;
|
||||||
|
astats->nmalloc_medium += arena->stats.nmalloc_medium;
|
||||||
|
astats->ndalloc_medium += arena->stats.ndalloc_medium;
|
||||||
|
astats->allocated_large += arena->stats.allocated_large;
|
||||||
|
astats->nmalloc_large += arena->stats.nmalloc_large;
|
||||||
|
astats->ndalloc_large += arena->stats.ndalloc_large;
|
||||||
|
|
||||||
|
for (i = 0; i < nbins; i++) {
|
||||||
|
bstats[i].nrequests += arena->bins[i].stats.nrequests;
|
||||||
|
#ifdef JEMALLOC_TCACHE
|
||||||
|
bstats[i].nfills += arena->bins[i].stats.nfills;
|
||||||
|
bstats[i].nflushes += arena->bins[i].stats.nflushes;
|
||||||
|
#endif
|
||||||
|
bstats[i].nruns += arena->bins[i].stats.nruns;
|
||||||
|
bstats[i].reruns += arena->bins[i].stats.reruns;
|
||||||
|
bstats[i].highruns += arena->bins[i].stats.highruns;
|
||||||
|
bstats[i].curruns += arena->bins[i].stats.curruns;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0, nlclasses = (chunksize - PAGE_SIZE) >> PAGE_SHIFT;
|
||||||
|
i < nlclasses;
|
||||||
|
i++) {
|
||||||
|
lstats[i].nrequests += arena->stats.lstats[i].nrequests;
|
||||||
|
lstats[i].highruns += arena->stats.lstats[i].highruns;
|
||||||
|
lstats[i].curruns += arena->stats.lstats[i].curruns;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
arena_stats_aprint(size_t nactive, size_t ndirty, const arena_stats_t *astats,
|
||||||
void (*write4)(const char *, const char *, const char *, const char *))
|
void (*write4)(const char *, const char *, const char *, const char *))
|
||||||
{
|
{
|
||||||
|
|
||||||
malloc_cprintf(write4,
|
malloc_cprintf(write4,
|
||||||
"dirty pages: %zu:%zu active:dirty, %llu sweep%s,"
|
"dirty pages: %zu:%zu active:dirty, %llu sweep%s,"
|
||||||
" %llu madvise%s, %llu purged\n",
|
" %llu madvise%s, %llu purged\n",
|
||||||
arena->nactive, arena->ndirty,
|
nactive, ndirty,
|
||||||
arena->stats.npurge, arena->stats.npurge == 1 ? "" : "s",
|
astats->npurge, astats->npurge == 1 ? "" : "s",
|
||||||
arena->stats.nmadvise, arena->stats.nmadvise == 1 ? "" : "s",
|
astats->nmadvise, astats->nmadvise == 1 ? "" : "s",
|
||||||
arena->stats.purged);
|
astats->purged);
|
||||||
|
|
||||||
malloc_cprintf(write4,
|
malloc_cprintf(write4,
|
||||||
" allocated nmalloc ndalloc\n");
|
" allocated nmalloc ndalloc\n");
|
||||||
malloc_cprintf(write4, "small: %12zu %12llu %12llu\n",
|
malloc_cprintf(write4, "small: %12zu %12llu %12llu\n",
|
||||||
arena->stats.allocated_small, arena->stats.nmalloc_small,
|
astats->allocated_small, astats->nmalloc_small,
|
||||||
arena->stats.ndalloc_small);
|
astats->ndalloc_small);
|
||||||
malloc_cprintf(write4, "medium: %12zu %12llu %12llu\n",
|
malloc_cprintf(write4, "medium: %12zu %12llu %12llu\n",
|
||||||
arena->stats.allocated_medium, arena->stats.nmalloc_medium,
|
astats->allocated_medium, astats->nmalloc_medium,
|
||||||
arena->stats.ndalloc_medium);
|
astats->ndalloc_medium);
|
||||||
malloc_cprintf(write4, "large: %12zu %12llu %12llu\n",
|
malloc_cprintf(write4, "large: %12zu %12llu %12llu\n",
|
||||||
arena->stats.allocated_large, arena->stats.nmalloc_large,
|
astats->allocated_large, astats->nmalloc_large,
|
||||||
arena->stats.ndalloc_large);
|
astats->ndalloc_large);
|
||||||
malloc_cprintf(write4, "total: %12zu %12llu %12llu\n",
|
malloc_cprintf(write4, "total: %12zu %12llu %12llu\n",
|
||||||
arena->stats.allocated_small + arena->stats.allocated_medium +
|
astats->allocated_small + astats->allocated_medium +
|
||||||
arena->stats.allocated_large, arena->stats.nmalloc_small +
|
astats->allocated_large, astats->nmalloc_small +
|
||||||
arena->stats.nmalloc_medium + arena->stats.nmalloc_large,
|
astats->nmalloc_medium + astats->nmalloc_large,
|
||||||
arena->stats.ndalloc_small + arena->stats.ndalloc_medium +
|
astats->ndalloc_small + astats->ndalloc_medium +
|
||||||
arena->stats.ndalloc_large);
|
astats->ndalloc_large);
|
||||||
malloc_cprintf(write4, "mapped: %12zu\n", arena->stats.mapped);
|
malloc_cprintf(write4, "mapped: %12zu\n", astats->mapped);
|
||||||
|
}
|
||||||
|
|
||||||
if (bins && arena->stats.nmalloc_small + arena->stats.nmalloc_medium >
|
static void
|
||||||
0) {
|
arena_stats_bprint(arena_t *arena, const malloc_bin_stats_t *bstats,
|
||||||
|
void (*write4)(const char *, const char *, const char *, const char *))
|
||||||
|
{
|
||||||
unsigned i, gap_start;
|
unsigned i, gap_start;
|
||||||
|
|
||||||
#ifdef JEMALLOC_TCACHE
|
#ifdef JEMALLOC_TCACHE
|
||||||
malloc_cprintf(write4,
|
malloc_cprintf(write4,
|
||||||
"bins: bin size regs pgs requests "
|
"bins: bin size regs pgs requests "
|
||||||
@ -1592,16 +1650,13 @@ arena_stats_print(arena_t *arena, bool bins, bool large,
|
|||||||
"newruns reruns maxruns curruns\n");
|
"newruns reruns maxruns curruns\n");
|
||||||
#endif
|
#endif
|
||||||
for (i = 0, gap_start = UINT_MAX; i < nbins; i++) {
|
for (i = 0, gap_start = UINT_MAX; i < nbins; i++) {
|
||||||
if (arena->bins[i].stats.nruns == 0) {
|
if (bstats[i].nruns == 0) {
|
||||||
if (gap_start == UINT_MAX)
|
if (gap_start == UINT_MAX)
|
||||||
gap_start = i;
|
gap_start = i;
|
||||||
} else {
|
} else {
|
||||||
if (gap_start != UINT_MAX) {
|
if (gap_start != UINT_MAX) {
|
||||||
if (i > gap_start + 1) {
|
if (i > gap_start + 1) {
|
||||||
/*
|
/* Gap of more than one size class. */
|
||||||
* Gap of more than one size
|
|
||||||
* class.
|
|
||||||
*/
|
|
||||||
malloc_cprintf(write4,
|
malloc_cprintf(write4,
|
||||||
"[%u..%u]\n", gap_start,
|
"[%u..%u]\n", gap_start,
|
||||||
i - 1);
|
i - 1);
|
||||||
@ -1626,15 +1681,15 @@ arena_stats_print(arena_t *arena, bool bins, bool large,
|
|||||||
arena->bins[i].reg_size,
|
arena->bins[i].reg_size,
|
||||||
arena->bins[i].nregs,
|
arena->bins[i].nregs,
|
||||||
arena->bins[i].run_size >> PAGE_SHIFT,
|
arena->bins[i].run_size >> PAGE_SHIFT,
|
||||||
arena->bins[i].stats.nrequests,
|
bstats[i].nrequests,
|
||||||
#ifdef JEMALLOC_TCACHE
|
#ifdef JEMALLOC_TCACHE
|
||||||
arena->bins[i].stats.nfills,
|
bstats[i].nfills,
|
||||||
arena->bins[i].stats.nflushes,
|
bstats[i].nflushes,
|
||||||
#endif
|
#endif
|
||||||
arena->bins[i].stats.nruns,
|
bstats[i].nruns,
|
||||||
arena->bins[i].stats.reruns,
|
bstats[i].reruns,
|
||||||
arena->bins[i].stats.highruns,
|
bstats[i].highruns,
|
||||||
arena->bins[i].stats.curruns);
|
bstats[i].curruns);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (gap_start != UINT_MAX) {
|
if (gap_start != UINT_MAX) {
|
||||||
@ -1649,7 +1704,10 @@ arena_stats_print(arena_t *arena, bool bins, bool large,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (large && arena->stats.nmalloc_large > 0) {
|
static void
|
||||||
|
arena_stats_lprint(const malloc_large_stats_t *lstats,
|
||||||
|
void (*write4)(const char *, const char *, const char *, const char *))
|
||||||
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
ssize_t gap_start;
|
ssize_t gap_start;
|
||||||
size_t nlclasses = (chunksize - PAGE_SIZE) >> PAGE_SHIFT;
|
size_t nlclasses = (chunksize - PAGE_SIZE) >> PAGE_SHIFT;
|
||||||
@ -1658,7 +1716,7 @@ arena_stats_print(arena_t *arena, bool bins, bool large,
|
|||||||
"large: size pages nrequests maxruns curruns\n");
|
"large: size pages nrequests maxruns curruns\n");
|
||||||
|
|
||||||
for (i = 0, gap_start = -1; i < nlclasses; i++) {
|
for (i = 0, gap_start = -1; i < nlclasses; i++) {
|
||||||
if (arena->stats.lstats[i].nrequests == 0) {
|
if (lstats[i].nrequests == 0) {
|
||||||
if (gap_start == -1)
|
if (gap_start == -1)
|
||||||
gap_start = i;
|
gap_start = i;
|
||||||
} else {
|
} else {
|
||||||
@ -1670,14 +1728,47 @@ arena_stats_print(arena_t *arena, bool bins, bool large,
|
|||||||
malloc_cprintf(write4,
|
malloc_cprintf(write4,
|
||||||
"%13zu %5zu %9llu %9zu %9zu\n",
|
"%13zu %5zu %9llu %9zu %9zu\n",
|
||||||
(i+1) << PAGE_SHIFT, i+1,
|
(i+1) << PAGE_SHIFT, i+1,
|
||||||
arena->stats.lstats[i].nrequests,
|
lstats[i].nrequests,
|
||||||
arena->stats.lstats[i].highruns,
|
lstats[i].highruns,
|
||||||
arena->stats.lstats[i].curruns);
|
lstats[i].curruns);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (gap_start != -1)
|
if (gap_start != -1)
|
||||||
malloc_cprintf(write4, "[%zu]\n", i - gap_start);
|
malloc_cprintf(write4, "[%zu]\n", i - gap_start);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
arena_stats_mprint(arena_t *arena, size_t nactive, size_t ndirty,
|
||||||
|
const arena_stats_t *astats, const malloc_bin_stats_t *bstats,
|
||||||
|
const malloc_large_stats_t *lstats, bool bins, bool large,
|
||||||
|
void (*write4)(const char *, const char *, const char *, const char *))
|
||||||
|
{
|
||||||
|
|
||||||
|
arena_stats_aprint(nactive, ndirty, astats, write4);
|
||||||
|
if (bins && astats->nmalloc_small + astats->nmalloc_medium > 0)
|
||||||
|
arena_stats_bprint(arena, bstats, write4);
|
||||||
|
if (large && astats->nmalloc_large > 0)
|
||||||
|
arena_stats_lprint(lstats, write4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
arena_stats_print(arena_t *arena, bool bins, bool large,
|
||||||
|
void (*write4)(const char *, const char *, const char *, const char *))
|
||||||
|
{
|
||||||
|
size_t nactive, ndirty;
|
||||||
|
arena_stats_t astats;
|
||||||
|
malloc_bin_stats_t bstats[nbins];
|
||||||
|
malloc_large_stats_t lstats[((chunksize - PAGE_SIZE) >> PAGE_SHIFT)];
|
||||||
|
|
||||||
|
nactive = 0;
|
||||||
|
ndirty = 0;
|
||||||
|
memset(&astats, 0, sizeof(astats));
|
||||||
|
memset(bstats, 0, sizeof(bstats));
|
||||||
|
memset(lstats, 0, sizeof(lstats));
|
||||||
|
|
||||||
|
arena_stats_merge(arena, &nactive, &ndirty, &astats, bstats, lstats);
|
||||||
|
arena_stats_mprint(arena, nactive, ndirty, &astats, bstats, lstats,
|
||||||
|
bins, large, write4);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -113,6 +113,8 @@ JEMALLOC_P(malloc_stats_print)(void (*write4)(const char *, const char *,
|
|||||||
{
|
{
|
||||||
char s[UMAX2S_BUFSIZE];
|
char s[UMAX2S_BUFSIZE];
|
||||||
bool general = true;
|
bool general = true;
|
||||||
|
bool merged = true;
|
||||||
|
bool unmerged = true;
|
||||||
bool bins = true;
|
bool bins = true;
|
||||||
bool large = true;
|
bool large = true;
|
||||||
|
|
||||||
@ -133,6 +135,12 @@ JEMALLOC_P(malloc_stats_print)(void (*write4)(const char *, const char *,
|
|||||||
case 'g':
|
case 'g':
|
||||||
general = false;
|
general = false;
|
||||||
break;
|
break;
|
||||||
|
case 'm':
|
||||||
|
merged = false;
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
unmerged = false;
|
||||||
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
bins = false;
|
bins = false;
|
||||||
break;
|
break;
|
||||||
@ -279,17 +287,51 @@ JEMALLOC_P(malloc_stats_print)(void (*write4)(const char *, const char *,
|
|||||||
malloc_cprintf(write4, " %12llu %12llu %12zu\n", huge_nmalloc,
|
malloc_cprintf(write4, " %12llu %12llu %12zu\n", huge_nmalloc,
|
||||||
huge_ndalloc, huge_allocated);
|
huge_ndalloc, huge_allocated);
|
||||||
|
|
||||||
|
if (merged) {
|
||||||
|
size_t nactive, ndirty;
|
||||||
|
arena_stats_t astats;
|
||||||
|
malloc_bin_stats_t bstats[nbins];
|
||||||
|
malloc_large_stats_t lstats[((chunksize - PAGE_SIZE) >>
|
||||||
|
PAGE_SHIFT)];
|
||||||
|
|
||||||
|
nactive = 0;
|
||||||
|
ndirty = 0;
|
||||||
|
memset(&astats, 0, sizeof(astats));
|
||||||
|
memset(bstats, 0, sizeof(bstats));
|
||||||
|
memset(lstats, 0, sizeof(lstats));
|
||||||
|
|
||||||
|
/* Create merged arena stats. */
|
||||||
|
for (i = 0; i < narenas; i++) {
|
||||||
|
arena = arenas[i];
|
||||||
|
if (arena != NULL) {
|
||||||
|
malloc_mutex_lock(&arena->lock);
|
||||||
|
arena_stats_merge(arena, &nactive,
|
||||||
|
&ndirty, &astats, bstats, lstats);
|
||||||
|
malloc_mutex_unlock(&arena->lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Print merged arena stats. */
|
||||||
|
malloc_cprintf(write4, "\nMerge arenas stats:\n");
|
||||||
|
/* arenas[0] is used only for invariant bin settings. */
|
||||||
|
arena_stats_mprint(arenas[0], nactive, ndirty, &astats,
|
||||||
|
bstats, lstats, bins, large, write4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unmerged) {
|
||||||
/* Print stats for each arena. */
|
/* Print stats for each arena. */
|
||||||
for (i = 0; i < narenas; i++) {
|
for (i = 0; i < narenas; i++) {
|
||||||
arena = arenas[i];
|
arena = arenas[i];
|
||||||
if (arena != NULL) {
|
if (arena != NULL) {
|
||||||
malloc_cprintf(write4, "\narenas[%u]:\n", i);
|
malloc_cprintf(write4,
|
||||||
|
"\narenas[%u]:\n", i);
|
||||||
malloc_mutex_lock(&arena->lock);
|
malloc_mutex_lock(&arena->lock);
|
||||||
arena_stats_print(arena, bins, large, write4);
|
arena_stats_print(arena, bins, large,
|
||||||
|
write4);
|
||||||
malloc_mutex_unlock(&arena->lock);
|
malloc_mutex_unlock(&arena->lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif /* #ifdef JEMALLOC_STATS */
|
#endif /* #ifdef JEMALLOC_STATS */
|
||||||
write4("--- End jemalloc statistics ---\n", "", "", "");
|
write4("--- End jemalloc statistics ---\n", "", "", "");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user