runtime,runtime/metrics: add heap goal and GC cycle metrics

This change adds three new metrics: the heap goal, GC cycle count, and
forced GC count. These metrics are identical to their MemStats
counterparts.

For #37112.

Change-Id: I5a5e8dd550c0d646e5dcdbdf38274895e27cdd88
Reviewed-on: https://go-review.googlesource.com/c/go/+/247044
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-06 16:47:58 +00:00 committed by Michael Knyszek
parent 07c3f65d53
commit a8b28ebc87
4 changed files with 86 additions and 8 deletions

View file

@ -7,6 +7,7 @@ package runtime
// Metrics implementation exported to runtime/metrics.
import (
"runtime/internal/atomic"
"unsafe"
)
@ -38,6 +39,34 @@ func initMetrics() {
return
}
metrics = map[string]metricData{
"/gc/cycles/automatic:gc-cycles": {
deps: makeStatDepSet(sysStatsDep),
compute: func(in *statAggregate, out *metricValue) {
out.kind = metricKindUint64
out.scalar = in.sysStats.gcCyclesDone - in.sysStats.gcCyclesForced
},
},
"/gc/cycles/forced:gc-cycles": {
deps: makeStatDepSet(sysStatsDep),
compute: func(in *statAggregate, out *metricValue) {
out.kind = metricKindUint64
out.scalar = in.sysStats.gcCyclesForced
},
},
"/gc/cycles/total:gc-cycles": {
deps: makeStatDepSet(sysStatsDep),
compute: func(in *statAggregate, out *metricValue) {
out.kind = metricKindUint64
out.scalar = in.sysStats.gcCyclesDone
},
},
"/gc/heap/goal:bytes": {
deps: makeStatDepSet(sysStatsDep),
compute: func(in *statAggregate, out *metricValue) {
out.kind = metricKindUint64
out.scalar = in.sysStats.heapGoal
},
},
"/gc/heap/objects:objects": {
deps: makeStatDepSet(heapStatsDep),
compute: func(in *statAggregate, out *metricValue) {
@ -248,14 +277,17 @@ func (a *heapStatsAggregate) compute() {
// heapStatsAggregate, means there could be some skew, but because of
// these stats are independent, there's no real consistency issue here.
type sysStatsAggregate struct {
stacksSys uint64
mSpanSys uint64
mSpanInUse uint64
mCacheSys uint64
mCacheInUse uint64
buckHashSys uint64
gcMiscSys uint64
otherSys uint64
stacksSys uint64
mSpanSys uint64
mSpanInUse uint64
mCacheSys uint64
mCacheInUse uint64
buckHashSys uint64
gcMiscSys uint64
otherSys uint64
heapGoal uint64
gcCyclesDone uint64
gcCyclesForced uint64
}
// compute populates the sysStatsAggregate with values from the runtime.
@ -264,6 +296,9 @@ func (a *sysStatsAggregate) compute() {
a.buckHashSys = memstats.buckhash_sys.load()
a.gcMiscSys = memstats.gcMiscSys.load()
a.otherSys = memstats.other_sys.load()
a.heapGoal = atomic.Load64(&memstats.next_gc)
a.gcCyclesDone = uint64(memstats.numgc)
a.gcCyclesForced = uint64(memstats.numforcedgc)
systemstack(func() {
lock(&mheap_.lock)

View file

@ -50,6 +50,29 @@ type Description struct {
// The English language descriptions below must be kept in sync with the
// descriptions of each metric in doc.go.
var allDesc = []Description{
{
Name: "/gc/cycles/automatic:gc-cycles",
Description: "Count of completed GC cycles generated by the Go runtime.",
Kind: KindUint64,
Cumulative: true,
},
{
Name: "/gc/cycles/forced:gc-cycles",
Description: "Count of completed forced GC cycles.",
Kind: KindUint64,
Cumulative: true,
},
{
Name: "/gc/cycles/total:gc-cycles",
Description: "Count of all completed GC cycles.",
Kind: KindUint64,
Cumulative: true,
},
{
Name: "/gc/heap/goal:bytes",
Description: "Heap size target for the end of the GC cycle.",
Kind: KindUint64,
},
{
Name: "/gc/heap/objects:objects",
Description: "Number of objects, live or unswept, occupying heap memory.",

View file

@ -44,6 +44,18 @@ the documentation of the Name field of the Description struct.
Supported metrics
/gc/cycles/automatic:gc-cycles
Count of completed GC cycles generated by the Go runtime.
/gc/cycles/forced:gc-cycles
Count of completed forced GC cycles.
/gc/cycles/total:gc-cycles
Count of all completed GC cycles.
/gc/heap/goal:bytes
Heap size target for the end of the GC cycle.
/gc/heap/objects:objects
Number of objects, live or unswept, occupying heap memory.

View file

@ -72,6 +72,14 @@ func TestReadMetrics(t *testing.T) {
checkUint64(t, name, samples[i].Value.Uint64(), mstats.Sys)
case "/gc/heap/objects:objects":
checkUint64(t, name, samples[i].Value.Uint64(), mstats.HeapObjects)
case "/gc/heap/goal:bytes":
checkUint64(t, name, samples[i].Value.Uint64(), mstats.NextGC)
case "/gc/cycles/automatic:gc-cycles":
checkUint64(t, name, samples[i].Value.Uint64(), uint64(mstats.NumGC-mstats.NumForcedGC))
case "/gc/cycles/forced:gc-cycles":
checkUint64(t, name, samples[i].Value.Uint64(), uint64(mstats.NumForcedGC))
case "/gc/cycles/total:gc-cycles":
checkUint64(t, name, samples[i].Value.Uint64(), uint64(mstats.NumGC))
}
}
}