美文网首页Go
使用pprof发现内存泄漏

使用pprof发现内存泄漏

作者: Go语言由浅入深 | 来源:发表于2021-05-02 15:26 被阅读0次
    image.png
    【译文】原文地址
    Golang是一个很神奇的语言。在开发系统应用或web应用时候,建议考虑采用Golang。Golang开发者的需求持续增长也是一个很好的证明。

    通过分析利弊我尝试了Go。我们有特定的使用场景,需要超低的构建时间,同时尽可能少使用资源。并且,我们使用微服务架构,因此可能使用不同的技术栈而不是单一的一种。

    总的来说,Golang+Graphql性能挺好的。每秒能处理大量的请求。正常请求和负载不会有问题。当我们使用压测和性能测试脚本的时候问题出现了。



    起初,我们发现应用异常是在大负载情况下。我们持续监测资源,性能测试完一段时间后,我们的服务使用了集群的大量资源(CPU和内存)。这使我们很沮丧和害怕因为没有达到我们使用GO的初衷。因此,我们分析发现问题并不是Golang语言问题,而是我们代码的bug。

    下面聊聊pprof

    来自pprof Github仓库 Github repo.)的简单介绍:
    pprof是一个用于对收集的数据分析和可视化工具。pprof从profile.proto文件读取收集的样本数据,并生成可视化的报告便于对数据进行分析。可以生成文本和图像报告。

    pprof详细文档链接。只需使用很少代码即可使用pprof。在生产环境中使用pprof也是安全的,它最大只需要5%的资源消耗。

    使用pprof

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


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

    如何解决

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

    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,可以看到go提供各种资源使用统计。

    生成图表

    保持前面程序运行,执行如下命令生成图表:
    1、内存统计

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

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

    2、CPU统计

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

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


    常见内存泄漏

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

    相关文章

      网友评论

        本文标题:使用pprof发现内存泄漏

        本文链接:https://www.haomeiwen.com/subject/phptdltx.html