内存逃逸
- 变量类型不确定的(
interface{}
) - 变量大小不确定的(切片等所占内存空间不确定的)
- 变量被外部引用的(注意是地址引用,如果是
int
等基本数据类型,则直接进行栈间拷贝,不会发生逃逸)
内存泄漏
内存泄漏(Memory Leak)是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。
内存泄漏分析工具:net/http/pprof
pprof是Go的性能分析工具。
在程序运行过程中,提供程序运行时的可视化信息:CPU、堆内存、goroutine栈运行情况等。
一、切片截取
func main() {
var str0 = "12345678901234567890"
str1 := str0[:10]
}
只要str1一直活跃,str0 就不会被回收
解决方法:将需要截取的部分copy克隆出来
二、goroutine泄露
goroutine泄露的本质是channel阻塞,无法继续向下执行,导致此goroutine关联的内存都无法释放,进一步造成内存泄露。
goroutine泄露的场景
泄露的场景不仅限于以下两类,但因channel相关的泄露是最多的。
channel的读或者写:
- 无缓冲channel的读写
- 有缓冲的channel因为缓冲区满了后的读写
- select操作所有case均阻塞