Go tool 问题排查- 协程泄漏问题

简介: Go tool 问题排查- 协程泄漏问题

下载测试代码


go get 中可以获取测试程序, 注意加上 -d 避免下载后自动安装。

Github


go get -d github.com/wolfogre/go-pprof-practice
cd $GOPATH/src/github.com/wolfogre/go-pprof-practice


如果 go get 下载不了, 可以 git clone 下载


gir clone https://github.com/wolfogre/go-pprof-practice


对代码进行编译

然后运行


go mod init
go mod tidy


最后再运行


go build
./go-pprof-practice

保持程序运行,打开浏览器访问 http://localhost:6060/debug/pprof/,可以看到如下页面:

image.png

内存泄漏问题排查

golang 和 Java 有点类似,自带了内存回收, 所以一般不会发生内存泄漏。但是也不绝对, golang 中 协程本身是可能泄漏的,或者叫做协程协程失控,进而导致内存泄漏。

启动程序

image.png

为了能更加图形化的展示,可以安装。graphviz


安装方式


brew install graphviz # for macos
apt install graphviz # for ubuntu
yum install graphviz # for centos

安装完成后,我们继续在上文的交互式终端里输入 web,注意,虽然这个命令的名字叫“web”,但它的实际行为是产生一个 .svg 文件,并调用你的系统里设置的默认打开 .svg 的程序打开它。如果你的系统里打开 .svg 的默认程序并不是浏览器(比如可能是你的代码编辑器),这时候你需要设置一下默认使用浏览器打开 .svg 文件

浏览器访问 http://localhost:6060/debug/pprof/

image.png

可以看到协程有 46 个, 使用 pprof 排查一下

go tool pprof http://localhost:6060/debug/pprof/goroutine

image.png

可以看到 cum 那一行 , 是 Drink 有40 个协程。

查看 list.Drink

image.png

输入 web, 浏览器可以看到 冒红的那部分。

image.png


可能这次问题藏得比较隐晦,但仔细观察还是不难发现,问题在于

github.com/wolfogre/go-pprof-practice/animal/canidae/wolf.(*Wolf).Drink 在不停地创建没有实际作用的协程:


func (w *Wolf) Drink() {
 log.Println(w.Name(), "drink")
 for i := 0; i < 10; i++ {
  go func() {
   time.Sleep(30 * time.Second)
  }()
 }
}


可以看到 Drink 函数 ,每次循环会有创建10个协程, 协程会 sleep 30s 才会退出,如果反复调用这个 Drink 函数, 那么会导致大量协程出现泄漏,协程数会增加。

相关文章
|
4月前
|
Go 调度 开发者
[go 面试] 深入理解进程、线程和协程的概念及区别
[go 面试] 深入理解进程、线程和协程的概念及区别
|
5月前
|
Java Go 调度
GO 协程
GO 协程
44 0
|
2月前
|
安全 Go 调度
探索Go语言的并发模式:协程与通道的协同作用
Go语言以其并发能力闻名于世,而协程(goroutine)和通道(channel)是实现并发的两大利器。本文将深入了解Go语言中协程的轻量级特性,探讨如何利用通道进行协程间的安全通信,并通过实际案例演示如何将这两者结合起来,构建高效且可靠的并发系统。
|
4月前
|
监控 Devops 测试技术
|
4月前
|
人工智能 Go
Go 等待协程完成
Go 等待协程完成
32 0
|
6月前
|
Go
如何在Go中进行文件操作以及如何使用协程来实现并发编程
如何在Go中进行文件操作以及如何使用协程来实现并发编程
84 2
|
7月前
|
安全 Go 调度
|
7月前
|
监控 负载均衡 算法
Golang深入浅出之-Go语言中的协程池设计与实现
【5月更文挑战第3天】本文探讨了Go语言中的协程池设计,用于管理goroutine并优化并发性能。协程池通过限制同时运行的goroutine数量防止资源耗尽,包括任务队列和工作协程两部分。基本实现思路涉及使用channel作为任务队列,固定数量的工作协程处理任务。文章还列举了一个简单的协程池实现示例,并讨论了常见问题如任务队列溢出、协程泄露和任务调度不均,提出了解决方案。通过合理设置缓冲区大小、确保资源释放、优化任务调度以及监控与调试,可以避免这些问题,提升系统性能和稳定性。
245 6
|
7月前
|
负载均衡 Go 调度
使用Go语言构建高性能的Web服务器:协程与Channel的深度解析
在追求高性能Web服务的今天,Go语言以其强大的并发性能和简洁的语法赢得了开发者的青睐。本文将深入探讨Go语言在构建高性能Web服务器方面的应用,特别是协程(goroutine)和通道(channel)这两个核心概念。我们将通过示例代码,展示如何利用协程处理并发请求,并通过通道实现协程间的通信和同步,从而构建出高效、稳定的Web服务器。
|
7月前
|
程序员 Go 数据处理