黑基网 首页 学院 电脑技术 查看内容

记一次内存泄露的debug过程

2016-2-8 22:44| 投稿: lofor

摘要: 在压测代码在线运行工具的时候,发现当并发比较高的时候程序占用的内存会飙升,而且在中断压测之后,内存占用并没有回落。第一个能想到的办法就是去看代码,但是大多数时候,自己写的代码,很难review出太多的问题; ...

在压测 代码在线运行 工具的时候,发现当并发比较高的时候程序占用的内存会飙升,而且在中断压测之后,内存占用并没有回落。

第一个能想到的办法就是去看代码,但是大多数时候,自己写的代码,很难review出太多的问题;于是就借助golang的pprof来定位问题。

在程序中嵌入 pprof

package main

import (
    "tool.lu/sandbox-server/app"
    "net/http"
    _ "net/http/pprof"
    "strconv"
    "runtime"
)

func main() {
    debug()
    server := app.NewApp()
    server.Run(":9090")
}

func debug() {
    go func() {
        // 这边是由于通过pprof发现问题之后,加的一段debug代码;后面会讲到
        http.HandleFunc("/go", func(w http.ResponseWriter, r *http.Request) {
            num := strconv.FormatInt(int64(runtime.NumGoroutine()), 10)
            w.Write([]byte(num))
        })
        http.ListenAndServe("localhost:6060", nil)
    }()
}

通过 go tool 工具,查看内存分配最多的 top 5

go tool pprof http://localhost:6060/debug/pprof/heap
top 5

查看代码,发现是 goroutine, ioPipe 的问题,一定是使用姿势出了问题:

于是便有了上面的那段代码, curl http://localhost:6060/go ,查看当前 go routine 的数量;于是猜测是因为 ioPipe 没有正确的关闭,引起 go routine 大量的产生,但是没有退出,耗费大量的内存;于是在异常退出前,主动关闭 ioPipe 的Reader,至此问题解决。

压测验证

本机

wrk -t5 -c20 -d10000s -s post.lua http://tool.lu

服务器

curl http://localhost:6060/go

总结

这是一个很小的bug,由于写代码的时候不仔细,return之前没有关闭资源造成,但却要花费不少的力气去解决;对语言自己提供的工具链需要熟悉在熟悉,这样不管在解决问题或者避免问题的时候,都能节省很多的时间。

小编推荐:欲学习电脑技术、系统维护、网络管理、编程开发和安全攻防等高端IT技术,请 点击这里 注册黑基账号,公开课频道价值万元IT培训教程免费学,让您少走弯路、事半功倍,好工作升职加薪!



免责声明:本文由投稿者转载自互联网,版权归原作者所有,文中所述不代表本站观点,若有侵权或转载等不当之处请联系我们处理,让我们一起为维护良好的互联网秩序而努力!联系方式见网站首页右下角。


鲜花

握手
1

雷人

路过

鸡蛋

刚表态过的朋友 (1 人)

  • 雷人

    匿名

相关阅读

最新评论


新出炉

返回顶部