Go中的逃逸分析

news2025/4/1 21:54:25

什么是逃逸?

逃逸是指一个变量本来应该分配在栈(stack)上,但由于某些原因,最终被分配到了堆(heap)上。

类比:

  • 栈就像一个临时的快餐盒,用来存放短期使用的数据。
  • 堆就像一个长期的仓库,用来存放需要长期存在的数据。
  • 如果快餐盒里的东西需要长期保存,就会被放到仓库里,这就是逃逸。

为什么会出现逃逸?

Go 的逃逸分析会决定变量是分配在栈上还是堆上。逃逸分析的准则是:

  1. 指向栈对象的指针不能存在堆上

    • 如果栈上的变量的地址被存储到堆上,那么当栈帧销毁时,堆上的指针会变成“悬空指针”,导致程序崩溃。
  2. 指向栈对象的指针不能超过该栈对象的存活期

    • 栈对象的生命周期很短,如果指针的生命周期比栈对象长,就会导致指针指向无效的内存。

类比:

  • 栈对象就像一个临时工,工作完成后就会离开。
  • 如果指针还指向这个临时工,但临时工已经走了,就会出问题。

逃逸分析的命令

go build -gcflags='-m -l' xxx.go
  • -m:打印逃逸分析的优化策略。
  • -l:取消内联(避免内联优化干扰分析结果)。

类比:

  • 这条命令就像是一个“侦探工具”,用来查看变量是否逃逸到堆上。

内存逃逸的影响

  1. 增加 GC 压力

    • 堆上的数据需要垃圾回收器(GC)管理,逃逸到堆上的变量会增加 GC 的负担。
  2. 造成内存碎片

    • 堆上的内存分配和释放不规则,容易导致内存碎片化,影响性能。

类比:

  • GC 就像清洁工,堆上的变量越多,清洁工的工作量就越大。
  • 内存碎片就像仓库里的空隙,浪费了空间。

什么时候会出现内存逃逸?

  1. 指针逃逸

    • 当栈上的变量的地址被传递到堆上时,变量会被分配到堆上。
    func foo() *int {
        x := 10 // x 是栈变量
        return &x // 返回 x 的地址,导致 x 逃逸到堆
    }
    
  2. 动态类型逃逸

    • 使用接口(interface)等动态类型时,变量可能会被分配到堆上。
    func bar() interface{} {
        x := 10 // x 是栈变量
        return x // x 被包装成接口类型,可能逃逸到堆
    }
    
  3. 栈空间不足

    • 如果栈空间不足以存放变量,变量会被分配到堆上。
  4. 变量大小不确定

    • 如果变量的大小在编译时无法确定,可能会被分配到堆上。

如何避免内存逃逸?

  1. 减少外部指针引用

    • 避免将栈变量的地址传递到堆上。
    func avoidEscape() {
        x := 10 // x 是栈变量
        use(x)  // 传递值而不是地址,避免逃逸
    }
    
  2. 性能要求高的函数避免使用接口类型

    • 接口类型会导致动态分配,尽量使用静态类型。
  3. 变量定义不要超过栈空间大小

    • 栈空间有限(通常几 KB),大变量尽量分配到堆上。
  4. 使用逃逸分析工具优化代码

    • 通过 -gcflags='-m -l' 查看哪些变量逃逸,并优化代码。

总结

逃逸分析是 Go 语言优化性能的重要工具。虽然逃逸到堆上会增加 GC 压力,但在某些场景下是不可避免的。通过合理设计代码结构和使用工具,可以尽量减少不必要的逃逸,提高程序性能。

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

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

相关文章

Spring 声明式事务 万字详解(通俗易懂)

目录 Δ前言 一、声明式事务快速入门 1.为什么需要声明式事务? 2.定义: 3.应用实例: 二、声明式事务的传播机制 1.引出问题: 2.传播机制分类: 3.应用实例: 三、声明式事务的隔离机制 1.四种隔离级别&…

MySQL 当中的锁

MySQL 当中的锁 文章目录 MySQL 当中的锁MySQL 中有哪些主要类型的锁?请简要说明MySQL 的全局锁有什么用?MySQL 的表级锁有哪些?作用是什么?元数据锁(MetaData Lock,MDL)意向锁(Inte…

[Linux]基础IO

基础IO C文件IO相关操作磁盘文件与内存文件inode(index node)硬链接与软连接硬链接软连接总结 动静态库静态库动态库总结 C文件IO相关操作 当前路径:进程运行的时候,所处的路径叫做当前路径 打开文件的时候,一定是进…

力扣刷题-热题100题-第27题(c++、python)

21. 合并两个有序链表 - 力扣(LeetCode)https://leetcode.cn/problems/merge-two-sorted-lists/description/?envTypestudy-plan-v2&envIdtop-100-liked 常规法 创建一个新链表,遍历list1与list2,将新链表指向list1与list2…

Vue3 其它API Teleport 传送门

Vue3 其它API Teleport 传送门 在定义一个模态框时,父组件的filter属性会影响子组件的position属性,导致模态框定位错误使用Teleport解决这个问题把模态框代码传送到body标签下

windows下安装sublime

sublime4 alpha 4098 版本 下载 可以根据待破解的版本选择下载 https://www.sublimetext.com/dev crack alpha4098 的licence 在----- BEGIN LICENSE ----- TwitterInc 200 User License EA7E-890007 1D77F72E 390CDD93 4DCBA022 FAF60790 61AA12C0 A37081C5 D0316412 4584D…

Java高级JVM知识点记录,内存结构,垃圾回收,类文件结构,类加载器

JVM是Java高级部分,深入理解程序的运行及原理,面试中也问的比较多。 JVM是Java程序运行的虚拟机环境,实现了“一次编写,到处运行”。它负责将字节码解释或编译为机器码,管理内存和资源,并提供运行时环境&a…

【STL】queue

q u e u e queue queue 是一种容器适配器,设计为先进先出( F i r s t I n F i r s t O u t , F I F O First\ In\ First\ Out,\ FIFO First In First Out, FIFO)的数据结构,有两个出口,将元素推入队列的操作称为 p u …

20250330-傅里叶级数专题之离散时间傅里叶变换(4/6)

4. 傅里叶级数专题之离散时间傅里叶变换 20250328-傅里叶级数专题之数学基础(0/6)-CSDN博客20250330-傅里叶级数专题之傅里叶级数(1/6)-CSDN博客20250330-傅里叶级数专题之傅里叶变换(2/6)-CSDN博客20250330-傅里叶级数专题之离散傅里叶级数(3/6)-CSDN博客20250330-傅里叶级数专…

漏洞挖掘---迅饶科技X2Modbus网关-GetUser信息泄露漏洞

一、迅饶科技 X2Modbus 网关 迅饶科技 X2Modbus 网关是功能强大的协议转换利器。“X” 代表多种不同通信协议,能将近 200 种协议同时转为 Modbus RTU 和 TCP 服务器 。支持 PC、手机端等访问监控,可解决组态软件连接不常见控制设备难题,广泛…

网络安全之前端学习(css篇2)

那么今天我们继续来学习css,预计这一章跟完后,下一章就是终章。然后就会开始js的学习。那么话不多说,我们开始吧。 字体属性 之前讲到了css可以改变字体属性,那么这里来详细讲一讲。 1.1字体颜色 之前讲到了对于字体改变颜色食…

PS底纹教程

1.ctrlshiftU 去色 2.新建纯色层 颜色中性灰;转换为智能对象 3.纯色层打开滤镜(滤镜库); 素描下找到半调图案,数值调成大小5对比1; 再新建一层,素描下找到撕边,对比拉到1&#x…

解决pyinstaller GUI打包时无法打包图片问题

当我们的python GuI在开发时。经常会用到图片作为背景,但是在打包后再启动GUI后却发现:原先调试时好端端的背景图片竟然不翼而飞或者直接报错。这说明图片没有被pyinstaller一起打包…… 要解决这个问题很简单,就是更改图片的存储方式。 tk…

蓝桥杯真题------R格式(高精度乘法,高精度加法)

对于高精度乘法和加法的同学可以学学这几个题 高精度乘法 高精度加法 文章目录 题意分析部分解全解 后言 题意 给出一个整数和一个浮点数,求2的整数次幂和这个浮点数相乘的结果最后四舍五入。、 分析 我们可以发现,n的范围是1000,2的1000次方非常大&am…

Nginx — Nginx安装证书模块(配置HTTPS和TCPS)

一、安装和编译证书模块 [rootmaster nginx]# wget https://nginx.org/download/nginx-1.25.3.tar.gz [rootmaster nginx]# tar -zxvf nginx-1.25.3.tar.gz [rootmaster nginx]# cd nginx-1.25.3 [rootmaster nginx]# ./configure --prefix/usr/local/nginx --with-http_stub_…

回调后门基础

回调后门概述 回调后门(Reverse Shell)是一种常见的攻击方式,攻击者通过受害主机主动连接到远程服务器(攻击者控制的机器),从而获得远程控制权限。 工作原理 受害者主机 运行一个恶意代码,尝…

深度学习 Deep Learning 第13章 线性因子模型

深度学习 Deep Learning 第13章 线性因子模型 内容概要 本章深入探讨了线性因子模型,这是一类基于潜在变量的概率模型,用于描述数据的生成过程。这些模型通过简单的线性解码器和噪声项捕捉数据的复杂结构,广泛应用于信号分离、特征提取和数…

【个人笔记】用户注册登录思路及实现 springboot+mybatis+redis

基本思路 获取验证码接口 验证码操作用了com.pig4cloud.plugin的captcha-core这个库。 AccountControl的"/checkCode"接口代码,通过ArithmeticCaptcha生成一张验证码图片,通过text()函数得到验证码的答案保存到变量code,然后把图…

聚类(Clustering)基础知识3

文章目录 一、聚类的性能评价1、聚类性能评价(1)聚类性能评价方法: 2、参考模型 (reference model)(1)数据集:(2)聚类结果:(3)参考模型&#xff1…

RK3588使用笔记:设置程序/服务开机自启

一、前言 一般将系统用作嵌入式设备时肯定要布置某些程序,这时候就需要对程序设置开机自己,否则每次都要人为启动,当有些嵌入式系统未连接显示屏或者无桌面环境去操作启动程序时,程序自启就是必须的了,本文介绍在纯li…