【golang】内存逃逸常见情况和避免方式

dongzaidong · · 3799 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

为什么要尽量避免内存逃逸?

因为如果变量的内存发生逃逸,它的生命周期就是不可知的,其会被分配到堆上,而堆上分配内存不能像栈一样会自动释放,为了解放程序员双手,专注于业务的实现,go实现了gc垃圾回收机制,但gc会影响程序运行性能,所以要尽量减少程序的gc操作。

常见内存逃逸情况

1、在方法内把局部变量指针返回,被外部引用,其生命周期大于栈,则溢出。
2、发送指针或带有指针的值到channel,因为编译时候无法知道那个goroutine会在channel接受数据,编译器无法知道什么时候释放。
3、在一个切片上存储指针或带指针的值。比如[]*string,导致切片内容逃逸,其引用值一直在堆上。
4、因为切片的append导致超出容量,切片重新分配地址,切片背后的存储基于运行时的数据进行扩充,就会在堆上分配。
5、在interface类型上调用方法,在Interface调用方法是动态调度的,只有在运行时才知道。

如何避免

1、go语言的接口类型方法调用是动态,因此不能在编译阶段确定,所有类型结构转换成接口的过程会涉及到内存逃逸发生,在频次访问较高的函数尽量调用接口。
2、不要盲目使用变量指针作为参数,虽然减少了复制,但变量逃逸的开销更大。
3、预先设定好slice长度,避免频繁超出容量,重新分配。


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:dongzaidong

查看原文:【golang】内存逃逸常见情况和避免方式

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

3799 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传