Go内存泄漏
示例1
package main
import (
"fmt"
"runtime"
"time"
)
func GetData() {
var ch chan struct{}
<-ch
}
func main() {
defer func() {
fmt.Println("goroutines: ", runtime.NumGoroutine())
}()
GetData()
time.Sleep(2 * time.Second)
}
输出会不会抛异常?为什么?看下输出结果:原因是chan未初始化,未初始化的chan要去消费,肯定fatal。看chan消费源码:
那怎么去解决这个问题呢?看示例2
示例2
package main
import (
"fmt"
"runtime"
"time"
)
func GetData() {
var ch chan struct{}
go func() {
<-ch
}()
}
func main() {
defer func() {
fmt.Println("goroutines: ", runtime.NumGoroutine())
}()
GetData()
time.Sleep(2 * time.Second)
}
输出是什么?为什么?看下结果:原因是把异常错误代码go出去了,不会影响到主goroutine的逻辑。
到这里你以为会万事大吉,准备上线了。上线之后不到one hour服务宕机了,你百思不得其解,问题出在哪里呢?
朋友们,出题就出在goroutine消费的是一个nil的chan,它一直阻塞在那里,你开辟的goroutine越多,泄漏的越多,导致内存耗尽触发OOM。
小结
可能朋友们觉得我只管写代码,泄漏等上完线再说吧,反正本地也验证不出来,你错了goleak
专门用来排查goroutine泄漏的,用起来吧。
github地址:https://github.com/uber-go/goleak
原文始发于微信公众号(堆栈future):Go内存泄漏
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/103469.html