aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Anthony Knyszek <mknyszek@google.com>2020-09-17 21:19:28 +0000
committerMichael Knyszek <mknyszek@google.com>2020-10-26 21:49:01 +0000
commit32d0eaa44e2d83cff6f0c1fa3d58af7627f3cd99 (patch)
tree576d9d8aff85829db8eac668a3684457841cd172
parent80c6b92ecb911409f57d06793a1213395b75ebe2 (diff)
downloadgo-32d0eaa44e2d83cff6f0c1fa3d58af7627f3cd99.tar.gz
go-32d0eaa44e2d83cff6f0c1fa3d58af7627f3cd99.zip
runtime: implement dumpmemstats in terms of readmemstats_m
Since MemStats is now populated directly and some values are derived, avoid duplicating the logic by instead populating the heap dump directly from MemStats (external version) instead of memstats (runtime internal version). Change-Id: I0bec96bfa02d2ffd1b56475779c124a760e64238 Reviewed-on: https://go-review.googlesource.com/c/go/+/255817 Trust: Michael Knyszek <mknyszek@google.com> Reviewed-by: Michael Pratt <mpratt@google.com>
-rw-r--r--src/runtime/heapdump.go76
1 files changed, 44 insertions, 32 deletions
diff --git a/src/runtime/heapdump.go b/src/runtime/heapdump.go
index 6fcd9746af..33e224d587 100644
--- a/src/runtime/heapdump.go
+++ b/src/runtime/heapdump.go
@@ -20,8 +20,19 @@ import (
func runtime_debug_WriteHeapDump(fd uintptr) {
stopTheWorld("write heap dump")
+ // Keep m on this G's stack instead of the system stack.
+ // Both readmemstats_m and writeheapdump_m have pretty large
+ // peak stack depths and we risk blowing the system stack.
+ // This is safe because the world is stopped, so we don't
+ // need to worry about anyone shrinking and therefore moving
+ // our stack.
+ var m MemStats
systemstack(func() {
- writeheapdump_m(fd)
+ // Call readmemstats_m here instead of deeper in
+ // writeheapdump_m because we might blow the system stack
+ // otherwise.
+ readmemstats_m(&m)
+ writeheapdump_m(fd, &m)
})
startTheWorld()
@@ -539,39 +550,40 @@ func dumpms() {
}
}
-func dumpmemstats() {
+//go:systemstack
+func dumpmemstats(m *MemStats) {
// These ints should be identical to the exported
// MemStats structure and should be ordered the same
// way too.
dumpint(tagMemStats)
- dumpint(memstats.alloc)
- dumpint(memstats.total_alloc)
- dumpint(memstats.sys)
- dumpint(memstats.nlookup)
- dumpint(memstats.nmalloc)
- dumpint(memstats.nfree)
- dumpint(memstats.alloc)
- dumpint(memstats.heap_sys.load())
- dumpint(memstats.heap_sys.load() - memstats.heap_inuse)
- dumpint(memstats.heap_inuse)
- dumpint(memstats.heap_released)
- dumpint(memstats.heap_objects)
- dumpint(memstats.stacks_inuse)
- dumpint(memstats.stacks_sys.load())
- dumpint(memstats.mspan_inuse)
- dumpint(memstats.mspan_sys.load())
- dumpint(memstats.mcache_inuse)
- dumpint(memstats.mcache_sys.load())
- dumpint(memstats.buckhash_sys.load())
- dumpint(memstats.gcMiscSys.load() + memstats.gcWorkBufInUse + memstats.gcProgPtrScalarBitsInUse)
- dumpint(memstats.other_sys.load())
- dumpint(memstats.next_gc)
- dumpint(memstats.last_gc_unix)
- dumpint(memstats.pause_total_ns)
+ dumpint(m.Alloc)
+ dumpint(m.TotalAlloc)
+ dumpint(m.Sys)
+ dumpint(m.Lookups)
+ dumpint(m.Mallocs)
+ dumpint(m.Frees)
+ dumpint(m.HeapAlloc)
+ dumpint(m.HeapSys)
+ dumpint(m.HeapIdle)
+ dumpint(m.HeapInuse)
+ dumpint(m.HeapReleased)
+ dumpint(m.HeapObjects)
+ dumpint(m.StackInuse)
+ dumpint(m.StackSys)
+ dumpint(m.MSpanInuse)
+ dumpint(m.MSpanSys)
+ dumpint(m.MCacheInuse)
+ dumpint(m.MCacheSys)
+ dumpint(m.BuckHashSys)
+ dumpint(m.GCSys)
+ dumpint(m.OtherSys)
+ dumpint(m.NextGC)
+ dumpint(m.LastGC)
+ dumpint(m.PauseTotalNs)
for i := 0; i < 256; i++ {
- dumpint(memstats.pause_ns[i])
+ dumpint(m.PauseNs[i])
}
- dumpint(uint64(memstats.numgc))
+ dumpint(uint64(m.NumGC))
}
func dumpmemprof_callback(b *bucket, nstk uintptr, pstk *uintptr, size, allocs, frees uintptr) {
@@ -642,7 +654,7 @@ func dumpmemprof() {
var dumphdr = []byte("go1.7 heap dump\n")
-func mdump() {
+func mdump(m *MemStats) {
// make sure we're done sweeping
for _, s := range mheap_.allspans {
if s.state.get() == mSpanInUse {
@@ -657,13 +669,13 @@ func mdump() {
dumpgs()
dumpms()
dumproots()
- dumpmemstats()
+ dumpmemstats(m)
dumpmemprof()
dumpint(tagEOF)
flush()
}
-func writeheapdump_m(fd uintptr) {
+func writeheapdump_m(fd uintptr, m *MemStats) {
_g_ := getg()
casgstatus(_g_.m.curg, _Grunning, _Gwaiting)
_g_.waitreason = waitReasonDumpingHeap
@@ -677,7 +689,7 @@ func writeheapdump_m(fd uintptr) {
dumpfd = fd
// Call dump routine.
- mdump()
+ mdump(m)
// Reset dump file.
dumpfd = 0