Go内存泄漏

简介: Go内存泄漏

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)
}

输出会不会抛异常?为什么?看下输出结果:

640.png

原因是chan未初始化,未初始化的chan要去消费,肯定fatal。看chan消费源码:

640.png

640.png


那怎么去解决这个问题呢?看示例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)
}


输出是什么?为什么?看下结果:

640.png

原因是把异常错误代码go出去了,不会影响到主goroutine的逻辑。


到这里你以为会万事大吉,准备上线了。上线之后不到one hour服务宕机了,你百思不得其解,问题出在哪里呢?


朋友们,出题就出在goroutine消费的是一个nil的chan,它一直阻塞在那里,你开辟的goroutine越多,泄漏的越多,导致内存耗尽触发OOM。


小结


可能朋友们觉得我只管写代码,泄漏等上完线再说吧,反正本地也验证不出来,你错了goleak专门用来排查goroutine泄漏的,用起来吧。

github地址:https://github.com/uber-go/goleak

相关文章
|
6月前
|
存储 Go iOS开发
掌握Go语言:探索Go语言指针,解锁高效内存操作与动态数据结构的奥秘(19)
掌握Go语言:探索Go语言指针,解锁高效内存操作与动态数据结构的奥秘(19)
|
6月前
|
存储 缓存 安全
Go语言内存模型深度解析
【2月更文挑战第16天】Go语言以其简洁的语法、强大的并发编程能力和高效的内存管理而备受开发者青睐。本文将对Go语言的内存模型进行深度解析,探讨其内存布局、内存分配与回收机制以及内存安全等方面的内容,帮助读者更好地理解和应用Go语言的内存管理特性。
|
24天前
|
Java 编译器 测试技术
go语言避免不必要的内存分配
【10月更文挑战第18天】
34 1
|
25天前
|
存储 算法 Java
Go语言的内存管理机制
【10月更文挑战第25天】Go语言的内存管理机制
23 2
|
3月前
|
存储 安全 编译器
Go 内存分布
该文章深入分析了Go语言中值的内存分布方式,特别是那些分布在多个内存块上的类型,如切片、映射、通道、函数、接口和字符串,并讨论了这些类型的内部结构和赋值时的行为,同时指出了“引用类型”这一术语在Go中的使用可能会引起的误解。
53 5
Go 内存分布
|
6月前
|
算法 Java Go
Go vs Java:内存管理与垃圾回收机制对比
对比了Go和Java的内存管理与垃圾回收机制。Java依赖JVM自动管理内存,使用堆栈内存并采用多种垃圾回收算法,如标记-清除和分代收集。Go则提供更多的手动控制,内存分配与释放由分配器和垃圾回收器协同完成,使用三色标记算法并发回收。示例展示了Java中对象自动创建和销毁,而Go中开发者需注意内存泄漏。选择语言应根据项目需求和技术栈来决定。
|
3月前
|
存储 安全 Go
Go 中的指针:了解内存引用
Go 中的指针:了解内存引用
|
3月前
|
缓存 Java 编译器
Go 中的内存布局和分配原理
Go 中的内存布局和分配原理
|
3月前
|
缓存 编解码 测试技术
使用Go实现健壮的内存型缓存
使用Go实现健壮的内存型缓存
69 2
|
3月前
|
存储 Go
Go 内存分配:结构体中的优化技巧
Go 内存分配:结构体中的优化技巧