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>
diff --git a/src/runtime/metrics.go b/src/runtime/metrics.go
index cf619cc..6595a43 100644
--- a/src/runtime/metrics.go
+++ b/src/runtime/metrics.go
@@ -7,6 +7,7 @@
// Metrics implementation exported to runtime/metrics.
import (
+ "runtime/internal/atomic"
"unsafe"
)
@@ -38,6 +39,34 @@
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 @@
// 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 @@
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)
diff --git a/src/runtime/metrics/description.go b/src/runtime/metrics/description.go
index 47013e1..66d229c 100644
--- a/src/runtime/metrics/description.go
+++ b/src/runtime/metrics/description.go
@@ -51,6 +51,29 @@
// 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.",
Kind: KindUint64,
diff --git a/src/runtime/metrics/doc.go b/src/runtime/metrics/doc.go
index 4ac44bb..9b44e73 100644
--- a/src/runtime/metrics/doc.go
+++ b/src/runtime/metrics/doc.go
@@ -44,6 +44,18 @@
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.
diff --git a/src/runtime/metrics_test.go b/src/runtime/metrics_test.go
index 6c0be7d..3724760 100644
--- a/src/runtime/metrics_test.go
+++ b/src/runtime/metrics_test.go
@@ -72,6 +72,14 @@
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))
}
}
}