golang 什么是内存逃逸?

什么是内存逃逸?

golang程序变量会携带有一组校验数据,用来证明它的整个生命周期是否在运行时完全可知。如果变量通过了这些校验,它就可以在栈上分配。否则就说它 逃逸 了,必须在堆上分配。

能引起变量逃逸到堆上的典型情况:

  • 在方法内把局部变量指针返回 局部变量原本应该在栈中分配,在栈中回收。但是由于返回时被外部引用,因此其生命周期大于栈,则溢出。
  • 发送指针或带有指针的值到 channel 中。 在编译时,是没有办法知道哪个 goroutine 会在 channel 上接收数据。所以编译器没法知道变量什么时候才会被释放。
  • 在一个切片上存储指针或带指针的值。 一个典型的例子就是 []*string 。这会导致切片的内容逃逸。尽管其后面的数组可能是在栈上分配的,但其引用的值一定是在堆上。
  • slice 的背后数组被重新分配了,因为 append 时可能会超出其容量( cap )。 slice 初始化的地方在编译时是可以知道的,它最开始会在栈上分配。如果切片背后的存储要基于运行时的数据进行扩充,就会在堆上分配。在 interface 类型上调用方法。
  • 在 interface 类型上调用方法都是动态调度的 —— 方法的真正实现只能在运行时知道。想像一个 io.Reader 类型的变量 r , 调用 r.Read(b) 会使得 r 的值和切片b 的背后存储都逃逸掉,所以会在堆上分配。
package main
import "fmt"
type A struct {s string
}
// 这是上面提到的 "在方法内把局部变量指针返回" 的情况
func foo(s string) *A {a := new(A) a.s = sreturn a //返回局部变量a,在C语言中妥妥野指针,但在go则ok,但a会逃逸到堆
}
func main() {a := foo("hello")b := a.s + " world"c := b + "!"fmt.Println(c)
}

执行go build -gcflags=-m main.go

go build -gcflags=-m main.go
# command-line-arguments
./main.go:7:6: can inline foo
./main.go:13:10: inlining call to foo
./main.go:16:13: inlining call to fmt.Println
/var/folders/45/qx9lfw2s2zzgvhzg3mtzkwzc0000gn/T/go-build409982591/b001/_gomod_.go:6:6: can inline init.0
./main.go:7:10: leaking param: s
./main.go:8:10: new(A) escapes to heap
./main.go:16:13: io.Writer(os.Stdout) escapes to heap
./main.go:16:13: c escapes to heap
./main.go:15:9: b + "!" escapes to heap
./main.go:13:10: main new(A) does not escape
./main.go:14:11: main a.s + " world" does not escape
./main.go:16:13: main []interface {} literal does not escape
<autogenerated>:1: os.(*File).close .this does not escape
  • ./main.go:8:10: new(A) escapes to heap 说明 new(A) 逃逸了,符合上述提到的常见情况中的第一种。
  • ./main.go:14:11: main a.s + " world" does not escape 说明 b 变量没有逃逸,因为它只在方法内存在,会在方法结束时被回收。
  • ./main.go:15:9: b + “!” escapes to heap 说明 c 变量逃逸,通过fmt.Println(a …interface{})打印的变量,都会发生逃逸,感兴趣的朋友可以去查查为什么。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/45635.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PHP企业工商年报大师微信小程序系统源码

&#x1f31f;轻松搞定年报难题&#xff01;&#x1f4bc; &#x1f680;【一键直达&#xff0c;年报不再繁琐】 还在为每年的企业工商年报而头疼吗&#xff1f;繁琐的表格、复杂的流程&#xff0c;让人望而却步&#xff1f;现在有了“企业工商年报大师”微信小程序&#xff…

Docker:基础概念、架构与网络模式详解

1.Docker的基本概念 1.1.什么是docker Docker是一个用于开发,交付和运行应用程序的开放平台.docker使您能够将应用程序域基础框架分开,以便你可以快速开发交付软件.使用docker,你可以管理你的基础架构以管理应用程序相同的方式.通过利用docker用于交付,测试和部署代码的方法,你…

vue3+antd+g2plot快速入门

创建项目 pnpm create vite选择vue和JavaScript 安装依赖 pnpm i ant-design-vue pnpm i antv/g2plot pnpm i vue-router完整代码 package.json {"name": "frontend","private": true,"version": "0.0.0","type&q…

解决Ubuntu 22.04 vscode搜狗拼音输入无法输入中文

关闭vscode 编辑~/.bashrc&#xff0c;添加以下内容 export GTK_IM_MODULExim export QT_IM_MODULExim export XMODIFIERSimfcitx source ~/.bashrc && code 重新加载环境变量后启动code&#xff0c;即可以正常使用搜狗拼音输入法了

MongoDB - 查询操作符:比较查询、逻辑查询、元素查询、数组查询

文章目录 1. 构造数据2. MongoDB 比较查询操作符1. $eq 等于1.1 等于指定值1.2 嵌入式文档中的字段等于某个值1.3 数组元素等于某个值1.4 数组元素等于数组值 2. $ne 不等于3. $gt 大于3.1 匹配文档字段3.2 根据嵌入式文档字段执行更新 4. $gte 大于等于5. $lt 小于6. $lte 小于…

java内部类的本质

定义在类内部&#xff0c;可以实现对外部完全隐藏&#xff0c;可以有更好的封装性&#xff0c;代码实现上也往往更为简洁。 内部类可以方便地访问外部类的私有变量&#xff0c;可以声明为private从而实现对外完全隐藏。 在Java中&#xff0c;根据定义的位置和方式不同&#xf…

什么是IOT 可编程控制系统

IOT可编程控制系统GF-MAXCC是一种基于物联网&#xff08;Internet of Things, IoT&#xff09;技术的可编程中央控制主机。它集成了多种先进的技术和功能&#xff0c;能够在物联网系统中发挥关键作用&#xff0c;实现对多种设备的集中管理和控制。 一、定义与概述 定义&#x…

虚幻引擎ue5如何调节物体锚点

当发现锚点不在物体上时&#xff0c;如何调节瞄点在物体上。 步骤1&#xff1a;按住鼠标中键拖动锚点&#xff0c;在透视图中多次调节锚点位置。 步骤2:在物体上点击鼠标右键点击-》锚定--》“设置为枢轴偏移”即可。

vue3的服务端渲染实战项目(1)共12节

一直在研究&#x1f9d0;Vue3的改变和提升&#xff0c;没有使用SSR怎么说是完全理解呢&#xff0c;接下来全套章节就带你一步一步了解服务端渲染的知识&#xff0c;后续对官网和项目的页面性能的考虑也会多一些思路。首先&#xff0c;老套路&#x1f604;三连问&#xff1a;什么…

昇思25天学习打卡营第二十四天|基于MindSpore通过GPT实现情感分类

基于MindSpore通过GPT实现情感分类 导入数据集 import osimport mindspore from mindnlp._legacy.engine import Evaluator, Trainer from mindnlp._legacy.engine.callbacks import BestModelCallback, CheckpointCallback from mindnlp._legacy.metrics import Accuracy fr…

219.贪心算法:柠檬水找零(力扣)

代码解决 class Solution { public:bool lemonadeChange(vector<int>& bills) {int num50, num100; // 初始化5美元和10美元的计数器for(int i0; i < bills.size(); i) // 遍历所有账单{if(bills[i]5) // 如果账单是5美元{num5; // 增加5美元的计数continue; // …

数据链路层协议 ------------- 以太网协议

链路层解决的问题 IP拥有将数据跨网络从一台主机送到另一台主机的能力&#xff0c;但IP并不能保证每次都能够将数据可靠的送到对端主机&#xff0c;因此IP需要上层TCP为其提供可靠性保证&#xff0c;比如数据丢包后TCP可以让IP重新发送数据&#xff0c;最终在TCP提供的可靠性机…

Linux系统密码重置

实验环境&#xff1a; Centos 7.9 背景&#xff1a; 找回root用户密码 1、首先&#xff0c;启动Linux系统进入开机界面&#xff0c;在界面中快速点击‘e’进入编辑界面&#xff0c;如图&#xff1a; 2、进入编辑界面会后往下翻找到“Linux16”内容所在的行数&#xff0c;在&q…

springboot商城综合项目自动化系统-计算机毕业设计源码051018

摘 要 目前电商系统商城项目管理极其频繁,迫切地需要自动化测试来代替人工繁琐而又重复的劳动。自动化测试相关的研究已经很多,但多数只是针对某一方面,比如单一接口或者单一页面或者性能等,而缺乏将接口、页面、持续集成系统和缺陷管理系统整合的自动化测试平台。本研究采用混…

Hadoop 2.0:主流开源云架构(二)

目录 二、Hadoop 2.0简述&#xff08;一&#xff09;Hadoop 2.0由来&#xff08;二&#xff09;Hadoop 2.0相关项目&#xff08;三&#xff09;Hadoop应用 三、Hadoop 2.0部署&#xff08;一&#xff09;部署综述&#xff08;二&#xff09;传统解压包部署 二、Hadoop 2.0简述 …

ARM功耗管理之睡眠锁

安全之安全(security)博客目录导读 思考&#xff1a;什么是睡眠锁&#xff1f;什么是唤醒源&#xff1f;什么是组合唤醒源&#xff1f; Kernel wakelocks的功能&#xff1a; 1&#xff09;允许driver创建wakelock以阻止睡眠、注销wakelock以允许睡眠。 2&#xff09;wake_lo…

计算机网络知识汇总

OSI七层模型 七层模型一般指开放系统互连参考模型&#xff0c;开放系统互连参考模型 &#xff08;Open System Interconnect 简称OSI&#xff09;&#xff0c;OSI参考模型是具有7个层次的框架&#xff0c;自底向上的7个层次分别是物理层、数据链路层、网络层、传输层、会话层、…

信息打点web篇--详解cdn识别与绕过

前言 欢迎来到我的博客 个人主页:北岭敲键盘的荒漠猫-CSDN博客 本文着重整理渗透过程中 cdn的相关知识点 cdn简要说明 我们一台服务器如果让外界访问&#xff0c;距离我们服务器近的地区访问的速度快&#xff0c;而远的地区访问速度则会大大减低。为了保证远区域用户的体验&a…

Ubuntu安装MATLAB

一、准备工作 下载MATLAB安装文件&#xff1a; 访问MathWorks官方网站&#xff08;MathWorks官网&#xff09;&#xff0c;下载适用于Linux的MATLAB安装文件。这通常是一个.iso镜像文件或.zip压缩文件。请注意选择与Ubuntu版本相匹配的MATLAB版本。创建安装目录&#xff1a; 打…

【eNSP模拟实验】单臂路由实现VLAN间通讯(复杂案例)

实验需求 如下图所示&#xff0c;PC1和PC2在vlan10下&#xff0c;PC3和PC4在vlan20下&#xff0c;Server1在vlan30下&#xff0c;需要实现这5台设备之间互相通讯。 实验操作 配置各个终端的ip地址 PC1~PC4都按照下图进行配置&#xff08;注意ip地址和网关有不同的地方&#…