关于Go语言MemoryProfile的一些问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于Go语言MemoryProfile的一些问题相关的知识,希望对你有一定的参考价值。
关于如何使用pprof进行profiling的问题,请参考https://studygolang.com/articles/7069,本文仅做一些补充。
1. http://xxx:6060/debug/pprof/heap?debug=1页面的解释
heap profile: 219: 286339776 [29791: 2945785336] @ heap/1048576
其中 219 —— 当前快照中看到的尚存活的堆对象的数量
286339776 —— 当前快照中看到的尚存活的堆对象的字节数
29791 —— 当前快照中看到的分配过的堆对象(包括已经释放的)的数量
29791 —— 当前快照中看到的分配过的堆对象(包括已经释放的)的字节数
1048576 —— MemProfileRate * 2
对于每个具体的对象,数据格式为
8: 62062592 [12: 93093888] @ 0x8fd38f 0x8fe4fa 0x8fa5f0 0x90714e 0x909b36 0x46bc31
其中, 8 —— 当前callstack上尚存活的对象数
62062592 —— 当前callstack上尚存活的对象占用字节数
12 —— 当前callstack上总过分配过的(包括已释放的)对象数
93093888 ——当前callstack上总过分配过的(包括已释放的)对象占用的字节数
@后面的内容 —— 当前callstack的栈帧,和下面解析的的callstack一致
这些内容都是在pprof.go文件中输出的,具体参看代码
fmt.Fprintf(w, "heap profile: %d: %d [%d: %d] @ heap/%d\n", total.InUseObjects(), total.InUseBytes(), total.AllocObjects, total.AllocBytes, 2*runtime.MemProfileRate) for i := range p { r := &p[i] fmt.Fprintf(w, "%d: %d [%d: %d] @", r.InUseObjects(), r.InUseBytes(), r.AllocObjects, r.AllocBytes) for _, pc := range r.Stack() { fmt.Fprintf(w, " %#x", pc) } fmt.Fprintf(w, "\n") printStackRecord(w, r.Stack(), false) } // Print memstats information too. // Pprof will ignore, but useful for people s := new(runtime.MemStats) runtime.ReadMemStats(s) fmt.Fprintf(w, "\n# runtime.MemStats\n") fmt.Fprintf(w, "# Alloc = %d\n", s.Alloc) fmt.Fprintf(w, "# TotalAlloc = %d\n", s.TotalAlloc) fmt.Fprintf(w, "# Sys = %d\n", s.Sys) fmt.Fprintf(w, "# Lookups = %d\n", s.Lookups) fmt.Fprintf(w, "# Mallocs = %d\n", s.Mallocs) fmt.Fprintf(w, "# Frees = %d\n", s.Frees) fmt.Fprintf(w, "# HeapAlloc = %d\n", s.HeapAlloc) fmt.Fprintf(w, "# HeapSys = %d\n", s.HeapSys) fmt.Fprintf(w, "# HeapIdle = %d\n", s.HeapIdle) fmt.Fprintf(w, "# HeapInuse = %d\n", s.HeapInuse) fmt.Fprintf(w, "# HeapReleased = %d\n", s.HeapReleased) fmt.Fprintf(w, "# HeapObjects = %d\n", s.HeapObjects) fmt.Fprintf(w, "# Stack = %d / %d\n", s.StackInuse, s.StackSys) fmt.Fprintf(w, "# MSpan = %d / %d\n", s.MSpanInuse, s.MSpanSys) fmt.Fprintf(w, "# MCache = %d / %d\n", s.MCacheInuse, s.MCacheSys) fmt.Fprintf(w, "# BuckHashSys = %d\n", s.BuckHashSys) fmt.Fprintf(w, "# GCSys = %d\n", s.GCSys) fmt.Fprintf(w, "# OtherSys = %d\n", s.OtherSys) fmt.Fprintf(w, "# NextGC = %d\n", s.NextGC) fmt.Fprintf(w, "# LastGC = %d\n", s.LastGC) fmt.Fprintf(w, "# PauseNs = %d\n", s.PauseNs) fmt.Fprintf(w, "# PauseEnd = %d\n", s.PauseEnd) fmt.Fprintf(w, "# NumGC = %d\n", s.NumGC) fmt.Fprintf(w, "# NumForcedGC = %d\n", s.NumForcedGC) fmt.Fprintf(w, "# GCCPUFraction = %v\n", s.GCCPUFraction) fmt.Fprintf(w, "# DebugGC = %v\n", s.DebugGC)
如果觉得heap profile中打印的活跃对象数和HeapObjects数量差别太大,可以将MemProfileRate设置为一个更小的值(默认为512*1024),设置为1,快照中就可以看到完整的堆对象分配情况。
以上是关于关于Go语言MemoryProfile的一些问题的主要内容,如果未能解决你的问题,请参考以下文章