go:如何定位内存cpu问题 在go web中,定位内存/cpu问题(内存泄漏,内存优化)可以这么做。 ##添加监听 ``` import _ "net/http/pprof" func main() { go func() { log.Println(http.ListenAndServe(":6060", nil)) }() ... ``` ## 网页查看数据 此时,可以在web浏览器中输入`http://localhost:6060/debug/pprof/`,并点击进入 heap,查看信息。 重要的数据在下面: ``` # runtime.MemStats # Alloc = 1950440 # TotalAlloc = 6346404496 # Sys = 27572472 ``` Alloc 指当前分配的内存,Sys指向系统申请的内存。正常情况下,Alloc的数值应该呈波动状(因为GC)。 这样,就能比较容易的发现内存泄漏的情况。 ##查看内存详情日志 但是,上面的信息还不足以优化代码,进入命令行,输入命令如下: ``` # 命令行交互界面 go tool pprof -alloc_space http://localhost:6060/debug/pprof/heap # 如果保留了现场,可以直接看当前使用量 go tool pprof -inuse_space http://127.0.0.1:6060/debug/pprof/heap # 加 -http=:8080 可以直接打开可视化界面,更简单 go tool pprof -http=:8080 -inuse_space http://127.0.0.1:6060/debug/pprof/heap ``` web界面  交互界面 输入 `top -cum`。 举例: ``` top -cum ... 28MB 0.44% 29.40% 1532.19MB 24.24% gcount/handlers.getArticleCount ``` 这里先讲下几个标准: - flat: 采样时,cpu状态下是该函数正在运行的次数 * 采样频率(10ms),即得到估算的函数运行”采样时间”。这里不包括函数等待子函数返回。内存状态下则为实际值。 - flat%: flat / 总采样时间值 - sum%: 前面所有行的 flat% 的累加值。 - cum: 采样时,该函数出现在调用堆栈的采样时间,包括函数等待子函数返回。因此 flat <= cum - cum%: cum / 总采样时间值 主要**关注cum和flat**就行了。 因为cum是链式的资源总合,我们很容易找到消耗链,然后使用list查看具体代码。具体上,我们关注flat的值就行了,找出大的优化它。 上面的例子中,getArticleCount 累计消耗1532M 内存。此时,用list查询这个函数,在交互界面输入 ``` list getArticleCount ROUTINE ======================== gcount/handlers.getArticleCount in handlers/ getclick.go 28MB 1.50GB (flat, cum) 24.24% of Total . . 15:) . . 16: . . 17://GetArticleCount传入id_list,返回相关文章点击量 . . 18:func getArticleCount(r *http.Request) (interface{}, int) { . . 19: logger.Debug("getArticleCount run") . 186.54MB 20: id_list := httpHelper.GetReqKey(r, "id_list") ... ``` 最上面一行是总量,然后是每行代码对应的内存消耗。 多调用几次list深挖,就能找出内存消耗的元凶啦。 ## 查看cpu详情 输入命令 ``` go tool pprof http://127.0.0.1:6060/debug/pprof/profile?seconds=10 ``` 等待一会,进入交互界面。 输入`top10`,查看cpu前十名:  发现第一名是syscall.Syscall,看不出来,我们继续。 输入`top -cum`  有点意思了,我们一路list,找到了关键地方:  从上面的图分析,可以发现cpu的消耗,主要在: - GetKafkaJobID(这个函数实际是json的解析); - json.Marshal/UnMarshal - http request 搞定收工。 ## 在benchmark的时候看看cpu ``` go test -bench=. -cpuprofile=cpu.prof # ... go tool pprof -http=:8080 cpu.prof ``` 打开图形界面享受吧。 来自 大脸猫 写于 2018-05-11 19:23 -- 更新于2021-05-20 11:23 -- 0 条评论