Golang 内存逃逸分析

马谦马谦马谦 Golang评论1,3173字数 703阅读2分20秒阅读模式

0x01 什么是逃逸

第一次听说逃逸是在雨痕学堂,一脸懵逼的百度了半天也没找到一个明确的说法,直到昨天在论坛上看到一篇关于变量逃逸的文章才明白。

因为函数都是运行在栈上的,在栈声明临时变量分配内存,函数运行完毕再回收该段栈空间,并且每个函数的栈空间都是独立的,其他代码都是不可访问的。但是在某些情况下,栈上的空间需要在该函数被释放后依旧能访问到,这时候就涉及到内存的逃逸了。

代码:

f1和f2两个函数都是创建一个变量返回,不同的是f1返回变量副本,f2返回变量指针。在大多数语言例如C/C++,类似f2的函数是不对的,因为d是一个临时变量,return过后就会被释放掉,返回毫无意义。但是在golang中,这种语法是允许的,它能正确的把d的地址返回到上层调用函数而不被释放。

正如上面所说,该函数在运行完毕后肯定是要释放的,内部分配的临时内存也要释放,所以d也应该被释放。而为了让d能被正确返回到上层调用,golang采取了一种内存策略,把d从栈拿到堆的中去,此时d就不会跟随f2一同消亡了,这个过程就是一次逃逸。

0x02 编译报告

代码中两个函数上方的go:noinline 注释是一个编译标记,让编译器不内联当前代码方便观察编译状态。因为这里代码十分简单,不给标记编译器会自动内联该段代码看不到效果。

在编译时可以通过gcflags选项带上-m参数查看到编译状态,-m一共可以携带四个:

通过第四行和第五行输出很直接就能看出,在代码的第16行,即函数f2return处,参数d产生了逃逸行为。

 
马谦马谦马谦
  • 本文由 马谦马谦马谦 发表于 2018年2月27日22:59:57
  • 转载请务必保留本文链接:https://www.dyxmq.cn/program/code/golang/golang-escape.html
解决gvm工具无法下载安装包的问题 Golang

解决gvm工具无法下载安装包的问题

GVM(Go Version Manager)是一款用于管理和切换不同Go语言版本的工具。它允许用户在同一台计算机上轻松安装、使用和管理多个Go版本,同时还能确保项目之间的依赖关系井然有序。GVM的主...
goland配置proto文件搜索路径 Golang

goland配置proto文件搜索路径

默认情况下,goland(jetbrains家的软件:idea、pycharm、phpstorm以及webstorm都是一样)安装protobuf插件后只会在一个特定的库路径下搜索proto文件。如果...
国内几个优质的Go Module代理仓库服务 Golang

国内几个优质的Go Module代理仓库服务

一、简介 go module公共代理仓库,代理并缓存go模块。你可以利用该代理来避免DNS污染导致的模块拉取缓慢或失败的问题,加速你的构建。 简单来说就是国内访问被墙,go get无法在线获取到仓库,...
Golang中glog库的使用方法 Golang

Golang中glog库的使用方法

一、关于glog库 golang中的glog库是google著名开源C++日志库glog的golang版本,在golang默认日志库的基础上做了更进一层的封装使得该库能更贴近日常使用。项目首页为gol...
匿名

发表评论

匿名网友
:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:
确定

拖动滑块以完成验证