go语言有完备的垃圾回收(gc)机制,但仍然可能出现内存泄漏的情况,如下:
开启一个协程:
func test() {
......
go func(){
for {
// do sth..
}
}()
.....
}
如果for循环内没有return或break,即使test()
函数结束,该协程也会继续运行,直到程序结束。
如果这不是我们的本意,就发生了协程泄漏
。协程泄漏的同时也会导致内存泄漏,因为协程一直在运行,里边用到的内存无法被gc回收。
当然,只要小心一点,我们基本不会犯这种错误。
但还有更隐蔽的情况,比如:封装了一个具有定期清理到期key功能的map库,我们就叫它TtlMap
。
TtlMap在初始化时会开启一个协程,负责定期删除到期的key,代码框架如下:
strcut TtlMap {
...
}
func New() *TtlMap {
map := &TtlMap{
...
}
//启动定期清理协程
go map.clear()
return map
}
func (m *TtlMap) clear() {
for {
//定期清理...
}
}
有一定go语言编程经验的人能看得出,这个map库是有问题的:没有提供结束map.clear()
协程的方法。
TtlMap作为一个局部变量时,定义它的函数结束后,由于c