开发者

Golang程序如何查找内存泄漏(pprof)

目录
  • golang程序查找内存泄漏
    • 1. 在main包中
    • 2. 编译
    • 3. 在目标机中运行刚编译出来的debug版本程序
    • 4. 执行
    • 5. 也可以使用以下命令直接导出调用图
  • 总结

    Golang程序查找内存泄漏

    1. 在main包中

    选择在一个单独文件js中加上pprof包引用并设置条件编译,这样不会与develop正式版本代码产生任何耦合。

    // +build debug
    
    package main
    
    import (
    	"net/http"
    	_ "net/http/pprof"
    )
    
    func init() {
    	go http.ListenAndServe(":18080", nil)
    }

    2. 编译

     gjavascripto build -tags debug .

    3. 在目标机中运行刚编译出来的debug版本程序

    本例中ip为随意编写的。

    4. 执行

    go tool pprof -inuse_space http://192.168.20.5:18080/debug/pprof/heap进入交互模式:

    [user@LAPTOP-LCP testtool]$ go tool pprof -inuse_space http://192.168.20.5:18080/debug/pprof/heap
    Fetching profile over HTTP from http://192.168.20.5:18080/debug/pprof/heap
    Saved profile in C:\Users\Noname\pprof\pprof.testtool.alloc_objects.alloc_space.inuse_objects.inuse_space.006.p
    b.gz
    File: testtool
    Type: inuse_space
    Time: Aug 16, 2022 at 2:24pm (CST)
    Entering iwww.devze.comnteractive mode (type "help" for commands, "o" for options)
    (pprof) top 10
    Showing nodes accounting for 27831.78kB, 100% of 27831.78kB total
    Showing top 10 nodes out of 35
    flat flat% sum% cum cum%
    11787.50kB 42.35% 42.35% 11787.50kB 42.35% runtime.allocm
    9382.95kB 33.71% 76.07% 9382.95kB 33.71% io.ReadAll
    2561.02kB 9.20% 85.27% 2561.02kB 9.20% runtime.malg
    1536.21kB 5javascript.52% 90.79% 1536.21kB 5.52% github.com/aws/aws-sdk-go/aws/endpoints.init
    514kB 1.85% 92.63% 514kB 1.85% bufio.NewReaderSize
    514kB 1.85% 94.48% 514kB 1.85% bufio.NewWriterSize
    512.08kB 1.84% 96.32% 512.08kB 1.84% net/http.newTransferWriter
    512.02kB 1.84% 98.16% 512.02kB 1.84% runtime.gcBgMarkWorker
    512kB 1.84% 100% 512kB 1.84% runtime.doaddtimer
    0 0% 100% 9382.95kB 33.71% jsio/ioutil.ReadAll
    (pprof)
    (pprof)

    交互界面使用top命令查看内存分配最多的函数。

    如果本机中有源代码,可以使用list命令查看源代码中哪一行分配的函数最多。

    (pprof)
    (pprof) list io.ReadAll
    Total: 27.18MB
    ROUTINE ======================== io.ReadAll in C:\Program Files\Go\src\io\io.go
    9.16MB 9.16MB (flat, cum) 33.71% of Total
    . . 626:func ReadAll(r Reader) ([]byte, error) {
    . . 627: b := make([]byte, 0, 512)
    . . 628: for {
    . . 629: if len(b) == cap(b) {
    . . 630: // Add more capacity (let append pick how much).
    9.16MB 9.16MB 631: b = append(b, 0)[:len(b)]
    . . 632: }
    . . 633: n, err := r.Read(b[len(b):cap(b)])
    . . 634: b = b[:len(b)+n]
    . . 635: if err != nil {
    . . 636: if err == EOF {
    (pprof)
    (pprof)

    5. 也可以使用以下命令直接导出调用图

    非常直观(需要安装Graphviz,详询Download | Graphviz)

    go tool pprof -inuse_space -png http://192.168.20.5:18080/debug/pprof/heap > heap.png

    Golang程序如何查找内存泄漏(pprof)

    可以在图片中直观地看到,调用过程中每个函数的内存使用占比。

    出现内存泄漏时,如果只查看一次很难确定真正出现内存泄露的代码位置,可以在程序运行一段时间后,程序出现内存泄露已经很明显后,再次查看内存占用分析图,找到两张图中内存占用比例相差最大的函数。

    总结

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜