Skip to content

Commit a8b28eb

Browse files
committed
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 <[email protected]> TryBot-Result: Go Bot <[email protected]> Trust: Michael Knyszek <[email protected]> Reviewed-by: Michael Pratt <[email protected]>
1 parent 07c3f65 commit a8b28eb

File tree

4 files changed

+86
-8
lines changed

4 files changed

+86
-8
lines changed

src/runtime/metrics.go

+43-8
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package runtime
77
// Metrics implementation exported to runtime/metrics.
88

99
import (
10+
"runtime/internal/atomic"
1011
"unsafe"
1112
)
1213

@@ -38,6 +39,34 @@ func initMetrics() {
3839
return
3940
}
4041
metrics = map[string]metricData{
42+
"/gc/cycles/automatic:gc-cycles": {
43+
deps: makeStatDepSet(sysStatsDep),
44+
compute: func(in *statAggregate, out *metricValue) {
45+
out.kind = metricKindUint64
46+
out.scalar = in.sysStats.gcCyclesDone - in.sysStats.gcCyclesForced
47+
},
48+
},
49+
"/gc/cycles/forced:gc-cycles": {
50+
deps: makeStatDepSet(sysStatsDep),
51+
compute: func(in *statAggregate, out *metricValue) {
52+
out.kind = metricKindUint64
53+
out.scalar = in.sysStats.gcCyclesForced
54+
},
55+
},
56+
"/gc/cycles/total:gc-cycles": {
57+
deps: makeStatDepSet(sysStatsDep),
58+
compute: func(in *statAggregate, out *metricValue) {
59+
out.kind = metricKindUint64
60+
out.scalar = in.sysStats.gcCyclesDone
61+
},
62+
},
63+
"/gc/heap/goal:bytes": {
64+
deps: makeStatDepSet(sysStatsDep),
65+
compute: func(in *statAggregate, out *metricValue) {
66+
out.kind = metricKindUint64
67+
out.scalar = in.sysStats.heapGoal
68+
},
69+
},
4170
"/gc/heap/objects:objects": {
4271
deps: makeStatDepSet(heapStatsDep),
4372
compute: func(in *statAggregate, out *metricValue) {
@@ -248,14 +277,17 @@ func (a *heapStatsAggregate) compute() {
248277
// heapStatsAggregate, means there could be some skew, but because of
249278
// these stats are independent, there's no real consistency issue here.
250279
type sysStatsAggregate struct {
251-
stacksSys uint64
252-
mSpanSys uint64
253-
mSpanInUse uint64
254-
mCacheSys uint64
255-
mCacheInUse uint64
256-
buckHashSys uint64
257-
gcMiscSys uint64
258-
otherSys uint64
280+
stacksSys uint64
281+
mSpanSys uint64
282+
mSpanInUse uint64
283+
mCacheSys uint64
284+
mCacheInUse uint64
285+
buckHashSys uint64
286+
gcMiscSys uint64
287+
otherSys uint64
288+
heapGoal uint64
289+
gcCyclesDone uint64
290+
gcCyclesForced uint64
259291
}
260292

261293
// compute populates the sysStatsAggregate with values from the runtime.
@@ -264,6 +296,9 @@ func (a *sysStatsAggregate) compute() {
264296
a.buckHashSys = memstats.buckhash_sys.load()
265297
a.gcMiscSys = memstats.gcMiscSys.load()
266298
a.otherSys = memstats.other_sys.load()
299+
a.heapGoal = atomic.Load64(&memstats.next_gc)
300+
a.gcCyclesDone = uint64(memstats.numgc)
301+
a.gcCyclesForced = uint64(memstats.numforcedgc)
267302

268303
systemstack(func() {
269304
lock(&mheap_.lock)

src/runtime/metrics/description.go

+23
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,29 @@ type Description struct {
5050
// The English language descriptions below must be kept in sync with the
5151
// descriptions of each metric in doc.go.
5252
var allDesc = []Description{
53+
{
54+
Name: "/gc/cycles/automatic:gc-cycles",
55+
Description: "Count of completed GC cycles generated by the Go runtime.",
56+
Kind: KindUint64,
57+
Cumulative: true,
58+
},
59+
{
60+
Name: "/gc/cycles/forced:gc-cycles",
61+
Description: "Count of completed forced GC cycles.",
62+
Kind: KindUint64,
63+
Cumulative: true,
64+
},
65+
{
66+
Name: "/gc/cycles/total:gc-cycles",
67+
Description: "Count of all completed GC cycles.",
68+
Kind: KindUint64,
69+
Cumulative: true,
70+
},
71+
{
72+
Name: "/gc/heap/goal:bytes",
73+
Description: "Heap size target for the end of the GC cycle.",
74+
Kind: KindUint64,
75+
},
5376
{
5477
Name: "/gc/heap/objects:objects",
5578
Description: "Number of objects, live or unswept, occupying heap memory.",

src/runtime/metrics/doc.go

+12
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,18 @@ the documentation of the Name field of the Description struct.
4444
4545
Supported metrics
4646
47+
/gc/cycles/automatic:gc-cycles
48+
Count of completed GC cycles generated by the Go runtime.
49+
50+
/gc/cycles/forced:gc-cycles
51+
Count of completed forced GC cycles.
52+
53+
/gc/cycles/total:gc-cycles
54+
Count of all completed GC cycles.
55+
56+
/gc/heap/goal:bytes
57+
Heap size target for the end of the GC cycle.
58+
4759
/gc/heap/objects:objects
4860
Number of objects, live or unswept, occupying heap memory.
4961

src/runtime/metrics_test.go

+8
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,14 @@ func TestReadMetrics(t *testing.T) {
7272
checkUint64(t, name, samples[i].Value.Uint64(), mstats.Sys)
7373
case "/gc/heap/objects:objects":
7474
checkUint64(t, name, samples[i].Value.Uint64(), mstats.HeapObjects)
75+
case "/gc/heap/goal:bytes":
76+
checkUint64(t, name, samples[i].Value.Uint64(), mstats.NextGC)
77+
case "/gc/cycles/automatic:gc-cycles":
78+
checkUint64(t, name, samples[i].Value.Uint64(), uint64(mstats.NumGC-mstats.NumForcedGC))
79+
case "/gc/cycles/forced:gc-cycles":
80+
checkUint64(t, name, samples[i].Value.Uint64(), uint64(mstats.NumForcedGC))
81+
case "/gc/cycles/total:gc-cycles":
82+
checkUint64(t, name, samples[i].Value.Uint64(), uint64(mstats.NumGC))
7583
}
7684
}
7785
}

0 commit comments

Comments
 (0)