使用pprof发现内存泄漏

pprof 简介

pprof 是一个用于对收集的数据分析和可视化工具。pprof 从 profile.proto 文件读取收集的样本数据,并生成可视化的报告便于对数据进行分析,可以生成文本和图像报告。
pprof 详细文档https://golang.org/pkg/net/http/pprof/。只需使用很少代码即可使用 pprof。在生产环境中使用 pprof 也是安全的,它最大只需要 5%的资源消耗。

使用 pprof

使用 pprof 工具,生成了内存和 cpu 的使用统计图(下面 PNG 格式图片)。一眼看去很明显发现 amqp_helper(队列处理文件)存在问题。我分析了代码,发现 amqp 连接没有关闭,导致内存占用。

图中框越大说明占有资源越多

如何解决

我推荐检查pprof.goinit()函数。将有助于理解/debug/pprof路由。使用如下模版:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
package main

import (
    "net/http"
    "net/http/pprof"
)

func main() {
    // other code

    // if your app is not serving on any port
    // then create a simple webserver
    go func() {
        log.Println(http.ListenAndServe("localhost:8082", nil))
    }()
}

当你访问http://localhost:8082/debug/pprof,可以看到 go 提供各种资源使用统计。

页面

生成图表

保持前面程序运行,执行如下命令生成图表:

1、内存统计

1
go tool pprof -png http://localhost:8082/debug/pprof/heap > heap.png

该命令会在当前目录生成 heap.png 文件。

2、CPU 统计

1
go tool proof -png http://localhost:8082/debug/pprof/profile > profile.png

以下是一个 CPU 统计的图表示例。使用上述命令,你可以创建和分析不同的统计数据。

CPU统计

常见内存泄漏

  • 没有正确的关闭或未关闭连接。包括数据库连接,队列连接,第三方库。
  • 没有正确使用 defer()函数
  • 使用大字符串/切片/子序列对其做多次操作。
  • 指针引用不使用的值
  • 孤悬的 Goroutine
  • 误用 Finalizer

以上来自https://www.jianshu.com/p/1bd06c3ae4d8