runtime: remove memstats.heap_idle

This statistic is updated in many places but for MemStats may be
computed from existing statistics. Specifically by definition
heap_idle = heap_sys - heap_inuse since heap_sys is all memory allocated
from the OS for use in the heap minus memory used for non-heap purposes.
heap_idle is almost the same (since it explicitly includes memory that
*could* be used for non-heap purposes) but also doesn't include memory
that's actually used to hold heap objects.

Although it has some utility as a sanity check, it complicates
accounting and we want fewer, orthogonal statistics for upcoming metrics
changes, so just drop it.

Change-Id: I40af54a38e335f43249f6e218f35088bfd4380d1
Reviewed-on: https://go-review.googlesource.com/c/go/+/246974
Run-TryBot: Michael Knyszek <mknyszek@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
This commit is contained in:
Michael Anthony Knyszek 2020-08-03 19:27:59 +00:00 committed by Michael Knyszek
parent ad863ba32a
commit c5dea8f387
3 changed files with 18 additions and 6 deletions

View File

@ -552,7 +552,7 @@ func dumpmemstats() {
dumpint(memstats.nfree)
dumpint(memstats.heap_alloc)
dumpint(memstats.heap_sys.load())
dumpint(memstats.heap_idle)
dumpint(memstats.heap_sys.load() - memstats.heap_inuse)
dumpint(memstats.heap_inuse)
dumpint(memstats.heap_released)
dumpint(memstats.heap_objects)

View File

@ -1239,7 +1239,6 @@ HaveSpan:
// Manually managed memory doesn't count toward heap_sys.
memstats.heap_sys.add(-int64(nbytes))
}
atomic.Xadd64(&memstats.heap_idle, -int64(nbytes))
// Publish the span in various locations.
@ -1317,7 +1316,6 @@ func (h *mheap) grow(npage uintptr) bool {
// size which is always > physPageSize, so its safe to
// just add directly to heap_released.
atomic.Xadd64(&memstats.heap_released, int64(asize))
atomic.Xadd64(&memstats.heap_idle, int64(asize))
// Recalculate nBase.
// We know this won't overflow, because sysAlloc returned
@ -1417,7 +1415,6 @@ func (h *mheap) freeSpanLocked(s *mspan, typ spanAllocType) {
// Manually managed memory doesn't count toward heap_sys, so add it back.
memstats.heap_sys.add(int64(nbytes))
}
atomic.Xadd64(&memstats.heap_idle, int64(nbytes))
// Mark the space as free.
h.pages.free(s.base(), s.npages)

View File

@ -34,7 +34,6 @@ type mstats struct {
// in manually-managed spans.
heap_alloc uint64 // bytes allocated and not yet freed (same as alloc above)
heap_sys sysMemStat // virtual address space obtained from system for GC'd heap
heap_idle uint64 // bytes in idle spans
heap_inuse uint64 // bytes in mSpanInUse spans
heap_released uint64 // bytes released to the os
@ -461,7 +460,23 @@ func readmemstats_m(stats *MemStats) {
stats.Frees = memstats.nfree
stats.HeapAlloc = memstats.heap_alloc
stats.HeapSys = memstats.heap_sys.load()
stats.HeapIdle = memstats.heap_idle
// By definition, HeapIdle is memory that was mapped
// for the heap but is not currently used to hold heap
// objects. It also specifically is memory that can be
// used for other purposes, like stacks, but this memory
// is subtracted out of HeapSys before it makes that
// transition. Put another way:
//
// heap_sys = bytes allocated from the OS for the heap - bytes ultimately used for non-heap purposes
// heap_idle = bytes allocated from the OS for the heap - bytes ultimately used for any purpose
//
// or
//
// heap_sys = sys - stacks_inuse - gcWorkBufInUse - gcProgPtrScalarBitsInUse
// heap_idle = sys - stacks_inuse - gcWorkBufInUse - gcProgPtrScalarBitsInUse - heap_inuse
//
// => heap_idle = heap_sys - heap_inuse
stats.HeapIdle = memstats.heap_sys.load() - memstats.heap_inuse
stats.HeapInuse = memstats.heap_inuse
stats.HeapReleased = memstats.heap_released
stats.HeapObjects = memstats.heap_objects