内存管理篇 (一):Go语言之逃逸

2023-11-06

本篇做为Go语言内存管理的第一篇文章,会从下面几个方向来讲述逃逸:

1.什么是逃逸?

2.为什么需要逃逸?

3.逃逸是怎么实现的?

一、什么是逃逸
在开始讲逃逸之前,我们先看一下,下面的两个例子。

例子1:stack.go的fun()返回的就是一个int变量。

例子2:mem.go的fun()返回的是*int变量,同时里面的返回值是&i。

源代码如下所示:

$ go tool compile -S stack.go //生成汇编语句

汇编结果分析:通过汇编可以看出来,在mem.go中的fun()中的变量i是通过newobject(XX)来生成的数据,这就说明,这个i是存储在对中。

备注:newobject(XX)函数的定义如下所示:

看到上面的例子,有没有觉得很奇怪,为什么mem.go的fun()函数中的i,明明是变量,但是却存储在堆中?

这个其实就是Go语言的逃逸,编译器通过执行静态代码的分析去决定,到底一个变量是应该分配到一个栈上面,还是需要逃逸到一个堆上面。

二、为什么需要逃逸
在分析逃逸之前,我们需要先看下Go语言中的堆。

在Go语言中,堆作为第二存储位置,Go会优先将数据存在栈里面的。堆是不会自己释放分配的内存的,需要通过GC(garbage collector)也就是垃圾收集器来回收这些分配好的内存。

Go中的栈数据,不能作为指针指向的存储位置。原因是:goroutine的栈会在栈扩容或者缩减的时候,指向不同的存储块。例子如下所示:

(摘自:https://play.golang.org/p/pxn5u4EBSI)

一旦指针指向这种栈存储位置,就会在运行的时候出现异常,而Go编译器要想解决这个问题,就会变的更复杂,所以Go的指针就不能指向栈中的存储地址。

想来这个应该也是Go逃逸的数据存储到堆中的原因了。

三、逃逸是怎么实现的
还是以mem.go作为例子,如下所示:

Output: //./mem

执行$ go build -gcflags "-m -m" mem.go 会得到下面的分析结果:

结果分析:通过输出的结果,我们可以看到line 10的 i, 会根据line 12的return &i来决定,将变量i 分配到堆上面。

 逃逸的内存分配如下所示:

1. main函数和fun函数,分别会有两个栈信息,分别为main frame和fun frame,如下图所示。

2.在fun frame中,变量i会在heap中分配对应的数据,地址为0xc000014080,变量值此时为0。

3.main函数在调用fun()之后,会copy一份i的值给变量a,此时的a的地址是0xc0000c028,存的值是i的地址0xc000014080,这个地址在堆中。

4.不管是在fun还是在main函数中,操作地址0xc000014080就可以取到对应的数值。

参考资料:
Language Mechanics On Escape Analysis:https://www.ardanlabs.com/blog/2017/05/language-mechanics-on-escape-analysis.html

Go's Memory Allocator - Overview:https://andrestc.com/post/go-memory-allocation-pt1/
————————————————
版权声明:本文为CSDN博主「灰子学技术」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zhghost/article/details/104075162

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

内存管理篇 (一):Go语言之逃逸 的相关文章

随机推荐

  • Safari开发者工具

    Safari开发者工具 1 开发者功能 2 开发者功能可以干什么 2 1 捕获模拟器的请求 1 开发者功能 Safari gt 首选项 gt 高级 gt 开启 在菜单栏中显示 开发 菜单 2 开发者功能可以干什么 2 1 捕获模拟器的请求
  • Android 自定义View :虚线矩形

    预览效果 涉及参数 斜线起点坐标 斜线可以忽略 斜线终点坐标 斜线可以忽略 矩形左上角坐标 矩形右下角坐标 其中 前两个参数用于绘制预览效果中矩形上方的斜线 如果不需要可以移除 本案例涉及视频外一个点指向视频内某块区域 因此参数略微复杂 除
  • CMD 命令换行

    CMD 命令换行 在执行较长的 cmd 命令或制作 cmd 命令脚本时 为了方便编写和阅读 有时需要在命令中加入适当的换行 基于不同的命令 有两种换行方式 普通命令 在要换行的地方输入 然后回车 再继续命令的输入 控制命令 如 if for
  • 如何使实时数据采集处理系统保持数据的高速传输

    如何使实时数据采集处理系统保持数据的高速传输 1引言 当前 越来越多的设计应用领域要求具有高精度的A D转换和实时处理功能 在实时数据采集处理系统设计中 一般需要考虑数据采集以及对采集数据的处理 而对于大数据量的实时数据采集处理系统来说 保
  • Linux服务器Java输出文件中文乱码

    使用下面语句查看编码 String encoding System getProperty file encoding 结果输出 ANSI X3 4 1968 从而导致中文乱码通过 locale 查看服务器系统编码 需要修改 1在tomca
  • 【论文阅读笔记】BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding

    BERT的出现使我们终于可以在一个大数据集上训练号一个深的神经网络 应用在很多NLP应用上面 BERT Pre training of Deep Bidirectional Transformers for Language Underst
  • css实现容器高度 适应 屏幕高度

    元素的高度默认是auto 被内容自动撑开 100 使得html的height与屏幕的高度相等 50 使得html的height等于屏幕的一半 若想让一个 div 的高度与屏幕高度自适应 始终充满屏幕 需要从html层开始层层添加height
  • 文本生成评估指标:ROUGE、BLEU详谈

    目录 1 自动摘要与机器翻译 1 自动摘要和机器翻译的定义和目标 2 自动摘要和机器翻译领域的挑战 2 ROUGE Recall Oriented Understudy for Gisting Evaluation 1 ROUGE 的目的和
  • AI虚拟点读机--详细注释解析恩培作品7

    感谢恩培大佬对项目进行了完整的实现 并将代码进行开源 供大家交流学习 一 项目简介 本项目最终达到的效果为手势控制虚拟点读机 如下所示 项目用python实现 调用opencv等库 使用SVM对字体进行分类 由以下步骤组成 1 使用Open
  • cd命令、pwd命令和环境变量PWD、OLDPWD的关联

    1 cd命令 cd命令这里不多介绍 cd 命令是返回上次所在的目录 2 PWD和OLDPWD环境变量 dai ubuntu env PWD home dai OLDPWD dai ubuntu 3 关联 1 当你输入 cd 命令返回上次的目
  • R语言之匹配篇

    2019独角兽企业重金招聘Python工程师标准 gt gt gt match match函数的声明如下 match x table nomatch NA integer incomparables NULL x 向量 要匹配的值 tabl
  • 深入MTK平台bootloader启动之【 Pre-loader -> Lk】分析笔记

    1 bootloader到kernel启动总逻辑流程图 ARM架构中 EL0 EL1是必须实现 EL2 EL3是选配 ELx跟层级对应关系 EL0 app EL1 Linux kernel lk EL2 hypervisor 虚拟化 EL3
  • Codeforces Round #589 (Div. 2)【数学 + 构造】

    A题 Distinct Digits 因为数的大小最长也就是5位 所以直接暴力求解即可 复杂度O 5 N include
  • C\C++ standard lib

    link
  • vue.js 解决空格报错!!!

    当我们初入vue js的时候 使用cli脚手架快速创建项目的时候 如果语法格式错误 这里主要指的是 空格多少引起的问题 找到 webpack base config js文件注释掉下面的东西 var path require path va
  • LeetCode 82. 删除排序链表中的重复元素 II

    题目链接 82 删除排序链表中的重复元素 II 设置虚拟头结点dummy不用考虑边界情况 p指针指向的是上一个没有重复的元素的位置 初始位置是dummy q从p gt next开始 一直走到第一个与q gt next不同元素的位置 删除中间
  • 经典目标检测算法—背景差分法、帧差法和三帧差法

    一 实验目的与要求 1 熟悉经典目标检测算法的原理 2 使用MATLAB语言编程实现背景差分法 帧差法和三帧差法 3 比较背景差分法 帧差法和三帧差法的特点 并了解该算法的应用条件 二 实验环境 Windows matlab 三 实验内容和
  • phpspreadsheet excel导入导出

    单个sheet页Excel2003版最大行数是65536行 Excel2007开始的版本最大行数是1048576行 Excel2003的最大列数是256列 2007以上版本是16384列 xlswriter xlswriter PHP 高性
  • Bean的四种注入方式

    1 set方法注入 2 构造器注入 3 静态工厂注入 4 实例工厂注入 我使用下面两个类来进行注入的演示 这两个类分别是User和Car类 Car类 public class Car 只包含基本数据类型的属性 private int spe
  • 内存管理篇 (一):Go语言之逃逸

    本篇做为Go语言内存管理的第一篇文章 会从下面几个方向来讲述逃逸 1 什么是逃逸 2 为什么需要逃逸 3 逃逸是怎么实现的 一 什么是逃逸 在开始讲逃逸之前 我们先看一下 下面的两个例子 例子1 stack go的fun 返回的就是一个in