V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ysmood
V2EX  ›  分享发现

检测 goroutine 泄漏

  •  1
     
  •   ysmood · 2022-04-01 17:21:48 +08:00 · 1354 次点击
    这是一个创建于 756 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如常见的异步生产消费模型,下面这段代码你能快速定位泄漏问题吗?如果你不停的访问这个 3000 端口,网站会内存泄漏。

    package main
    
    import (
    	"fmt"
    	"net/http"
    )
    
    func main() {
    	_ = http.ListenAndServe(":3000", http.HandlerFunc(handle))
    }
    
    func handle(_ http.ResponseWriter, _ *http.Request) {
    	c := make(chan int)
    	go produce(c)
    	go consume(c)
    }
    
    func produce(c chan int) {
    	for i := range "..." {
    		c <- i
    	}
    }
    
    func consume(c chan int) {
    	for i := range c {
    		fmt.Println(i)
    	}
    }
    

    我们可以用 gotrace 来自动定位泄漏点,添加一个 main_test.go 文件:

    package main
    
    import (
    	"testing"
    
    	"github.com/ysmood/gotrace"
    )
    
    func TestHandle(t *testing.T) {
    	gotrace.CheckLeak(t, 0)
    
    	handle(nil, nil)
    }
    

    运行 GODEBUG="tracebackancestors=10" go test,等待 3 秒后就可以看到打印信息如下:

    --- FAIL: TestHandle (3.00s)
        main_test.go:10: leaking goroutines: goroutine 6 [chan receive]:
            play.consume(0x0)
            	/Users/ys/repos/play/default/main.go:25 +0x74
    

    可以看到第 25 行的 range 卡住了,原因是 chan receive,它在等待 c 的新消息,然而 produce 函数已经退出不会再往 c 里发布消息了。

    修正的方法很多,比如把 produce 修改为:

    func produce(c chan int) {
    	for i := range "..." {
    		c <- i
    	}
    	close(c)
    }
    

    再运行 go test 测试就立马成功结束了。

    想了解更多 gotrace 用法可以移步 https://github.com/ysmood/gotrace

    3 条回复    2022-04-02 01:19:20 +08:00
    Nxxx
        1
    Nxxx  
       2022-04-01 23:48:45 +08:00
    最近刚好遇到这个问题 回去是下 以 star
    zagfai
        2
    zagfai  
       2022-04-02 00:53:48 +08:00
    严格来说又不算 bug 算 feature 吧?。。。
    ysmood
        3
    ysmood  
    OP
       2022-04-02 01:19:20 +08:00
    @zagfai 什么意思?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   927 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 39ms · UTC 21:25 · PVG 05:25 · LAX 14:25 · JFK 17:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.