runtime: apply looser bound to /gc/heap/live:bytes in test

/gc/heap/live:bytes may exceed MemStats.HeapAlloc, even when all data is
flushed, becuase the GC may double-count objects when marking them. This
is an intentional design choice that is largely inconsequential. The
runtime is already robust to it, and the condition is rare.

Fixes #60607.

Change-Id: I4da402efc24327328d2d8780e4e49961b189f0ea
Reviewed-on: https://go-review.googlesource.com/c/go/+/501858
Auto-Submit: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
Run-TryBot: Michael Knyszek <mknyszek@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
Michael Anthony Knyszek 2023-06-08 17:08:52 +00:00 committed by Gopher Robot
parent 0cc58564f6
commit 7b325ba27d
1 changed files with 10 additions and 2 deletions

View File

@ -143,8 +143,16 @@ func TestReadMetrics(t *testing.T) {
case "/gc/heap/frees:objects":
frees = samples[i].Value.Uint64()
case "/gc/heap/live:bytes":
if live := samples[i].Value.Uint64(); live > mstats.HeapAlloc {
t.Errorf("live bytes: %d > heap alloc: %d", live, mstats.HeapAlloc)
// Check for "obviously wrong" values. We can't check a stronger invariant,
// such as live <= HeapAlloc, because live is not 100% accurate. It's computed
// under racy conditions, and some objects may be double-counted (this is
// intentional and necessary for GC performance).
//
// Instead, check against a much more reasonable upper-bound: the amount of
// mapped heap memory. We can't possibly overcount to the point of exceeding
// total mapped heap memory, except if there's an accounting bug.
if live := samples[i].Value.Uint64(); live > mstats.HeapSys {
t.Errorf("live bytes: %d > heap sys: %d", live, mstats.HeapSys)
} else if live == 0 {
// Might happen if we don't call runtime.GC() above.
t.Error("live bytes is 0")