Golang 里怎么避免内存逃逸?
参考解析
题目来源:蚂蚁
答案:
- 不要盲目使用变量指针作为参数,虽然减少了复制,但变量逃逸的开销更大。
- 预先设定好slice长度,避免频繁超出容量,重新分配。
- 一个经验是,指针指向的数据大部分在堆上分配的,请注意。
出现内存逃逸的情况有:
1.发送指针或带有指针的值到channel,因为编译时候无法知道那个goroutine会在channel接受数据,编译器无法知道什么时候释放。
2.在一个切片上存储指针或带指针的值。比如[]*string,导致切片内容逃逸,其引用值一直在堆上。
3.切片的append导致超出容量,切片重新分配地址,切片背后的存储基于运行时的数据进行扩充,就会在堆上分配。
4.调用接口类型时,接口类型的方法调用是动态调度,实际使用的具体实现只能在运行时确定,如一个接口类型为io.Reader的变量r,对r.Read(b)的调用将导致r的值和字节片b的后续转义并因此分配到堆上。
5.在方法内把局部变量指针返回,被外部引用,其生命周期大于栈,导致内存溢出。