From 8168e1f77319a31cc07b6b9a59d8c64cf1335b45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Rainone?= Date: Sun, 24 Sep 2023 19:28:50 +0200 Subject: [PATCH] internal/plots: add 'memory-classes' plot --- internal/plot/plots_go119.go | 125 +++++++++++++++++++++++++++++++++-- 1 file changed, 118 insertions(+), 7 deletions(-) diff --git a/internal/plot/plots_go119.go b/internal/plot/plots_go119.go index 60bf9406..5aaa7a55 100644 --- a/internal/plot/plots_go119.go +++ b/internal/plot/plots_go119.go @@ -3,9 +3,12 @@ package plot -import ( - "runtime/metrics" -) +import "runtime/metrics" + +func init() { + registerPlotFunc(makeGCCyclesPlot) + registerPlotFunc(makeMemoryClassesPlot) +} /* * GC cycles @@ -16,10 +19,6 @@ var _ = registerRuntimePlot("gc-cycles", "/gc/cycles/total:gc-cycles", ) -func init() { - registerPlotFunc(makeGCCyclesPlot) -} - type gcCycles struct { enabled bool @@ -93,3 +92,115 @@ func (p *gcCycles) values(samples []metrics.Sample) any { return ret } + +/* Memory classes */ + +/* +/memory/classes/os-stacks:bytes + Stack memory allocated by the underlying operating system. + In non-cgo programs this metric is currently zero. This may + change in the future.In cgo programs this metric includes + OS thread stacks allocated directly from the OS. Currently, + this only accounts for one stack in c-shared and c-archive build + modes, and other sources of stacks from the OS are not measured. + This too may change in the future. + +/memory/classes/other:bytes + Memory used by execution trace buffers, structures for debugging + the runtime, finalizer and profiler specials, and more. + +/memory/classes/profiling/buckets:bytes + Memory that is used by the stack trace hash map used for + profiling. + +/memory/classes/total:bytes + All memory mapped by the Go runtime into the current process + as read-write. Note that this does not include memory mapped + by code called via cgo or via the syscall package. Sum of all + metrics in /memory/classes. +*/ + +/* + * mspan mcache + */ +var _ = registerRuntimePlot("memory-classes", + "/memory/classes/os-stacks:bytes", + "/memory/classes/other:bytes", + "/memory/classes/profiling/buckets:bytes", + "/memory/classes/total:bytes", +) + +type memoryClasses struct { + enabled bool + + idxOSStacks int + idxOther int + idxProfBuckets int + idxTotal int +} + +func makeMemoryClassesPlot(idxs map[string]int) runtimeMetric { + idxOSStacks, ok1 := idxs["/memory/classes/os-stacks:bytes"] + idxOther, ok2 := idxs["/memory/classes/other:bytes"] + idxProfBuckets, ok3 := idxs["/memory/classes/profiling/buckets:bytes"] + idxTotal, ok4 := idxs["/memory/classes/total:bytes"] + + return &memoryClasses{ + enabled: ok1 && ok2 && ok3 && ok4, + idxOSStacks: idxOSStacks, + idxOther: idxOther, + idxProfBuckets: idxProfBuckets, + idxTotal: idxTotal, + } +} + +func (p *memoryClasses) name() string { return "memory-classes" } +func (p *memoryClasses) isEnabled() bool { return p.enabled } + +func (p *memoryClasses) layout(_ []metrics.Sample) any { + s := Scatter{ + Name: p.name(), + Title: "Memory classes", + Type: "scatter", + Events: "lastgc", + Subplots: []Subplot{ + { + Name: "os stacks", + Unitfmt: "%{y:.4s}B", + }, + { + Name: "other", + Unitfmt: "%{y:.4s}B", + }, + { + Name: "profiling buckets", + Unitfmt: "%{y:.4s}B", + }, + { + Name: "total", + Unitfmt: "%{y:.4s}B", + }, + }, + + InfoText: `OS stacks is /memory/classes/os-stacks, stack memory allocated by the underlying operating system. +Other is /memory/classes/other, memory used by execution trace buffers, structures for debugging the runtime, finalizer and profiler specials, and more. +Profiling buckets is /memory/classes/profiling/buckets, memory that is used by the stack trace hash map used for profiling. +Total is /memory/classes/total, all memory mapped by the Go runtime into the current process as read-write.`, + } + s.Layout.Yaxis.Title = "bytes" + s.Layout.Yaxis.TickSuffix = "B" + return s +} + +func (p *memoryClasses) values(samples []metrics.Sample) any { + osStacks := samples[p.idxOSStacks].Value.Uint64() + other := samples[p.idxOther].Value.Uint64() + profBuckets := samples[p.idxProfBuckets].Value.Uint64() + total := samples[p.idxTotal].Value.Uint64() + return []uint64{ + osStacks, + other, + profBuckets, + total, + } +}