golang逃逸分析

1.1 逃逸分析是什么

逃逸分析是指编译器在执行静态代码分析后,对内存管理进行的优化和简化。

在编译原理中,分析指针动态范围的方法被称为逃逸分析。通俗来讲,当一个对象的指针被多个方法或线程引用时,则称这个指针发生了逃逸。逃逸分析决定一个变量是分配在堆上还是分配在栈上。

1.2 逃逸分析有什么作用

逃逸分析把变量合理地分配到它该去的地方,“找准自己的位置”。既是使用 new 函数申请到的内存,如果编译器发现这块内存在退出函数后就没有使用了,那就分配到栈上,毕竟栈上的内存分配比堆上快很多;反之,既是表面上只是一个普通的变量,但是经过编译器的逃逸分析后发现,在函数之外还有其他的地方在引用,那就分配到堆上。真正做到 “按需分配”。

如果变量都分配到堆上,堆不像栈可以自动清理。就会引起 Go 频繁地进行垃圾回收,而垃圾回收会占用比较大的系统开销。

堆和栈相比,堆适合不可预知大小的内存分配。但是为此付出的代价是分配速度较慢,而且会形成内存碎片;栈内存分配则非常快。栈分配内存只需通过 PUSH 指令,并且会被自动释放;而堆分配首先需要去找到一块大小合适的内存块,之后要通过垃圾回收才能释放。

通过逃逸分析,可以尽量把那些不需要分配到堆上的变量直接分配到栈上,堆上的变量变少了,会减轻堆内存分配的开销,同时也会减少垃圾回收(Garbage Collction,GC)的压力,提高程序运行速度。

1.3 逃逸分析是怎么完成的

Go 语言逃逸分析最基本的原则是:如果一个函数返回对一个变量的引用,那么这个变量就会发生逃逸。

编译器会分析代码的特征和代码的生命周期,Go 中的变量只有在编译器可以证明在函数返回后不再被引用,才分配到栈上,其他情况下都是直接分配到堆上。

Go 语言里没有一个关键字或者函数可以直接让变量被编译器分配到堆上。相反,编译器通过分析代码来决定将变量分配到何处。

对一个变量取地址,可能会被分配到堆上。但是编译器进行逃逸分析后,如果考虑到在函数返回后,此变量不会被引用,那么还是可能分配到栈上。简单来说,编译器会根据变量是否被外部引用来决定是否逃逸:

如果变量在函数外部没有被引用,则优先放到栈上。
如果变量在函数外部存在引用,则必定放在堆上。
针对第一条,放到堆上的情形:定义了一个很大的数组,需要申请的内存过大,超过了栈的存储能力。

1.4 如何确定是否发生逃逸分析

Go 提供了相关的命令,可以查看变量是否发生了逃逸。例子如下:

package  mainimport  "fmt"func  foo() *int {t :=  3return  &t
}func  main() {x :=  foo()fmt.Println(*x)
}

foo 函数返回一个局部变量的指针,使用 main 函数里变量 x 接收它。执行如下命令:

go build -gcflags '-m-l' main.go

其中 -gcflags 参数用于启用编译器支持的额外标志。例如, -m 用于输出编译器的优化细节(包括使用逃逸分析这种优化),相反可以使用 -N 来关闭编译器优化;而 -l 则用于禁用 foo 函数的内联优化,防止逃逸被编译器通过内联优化彻底的抹除。得到如下输出:

### command-line-arguments
src/main.go:7:9: &t escapes to heap
src/main.go:6:7: moved to heap: t
src/main.go:12:14: *x escapes to heap
src/main.go:12:13: main ... argument does not escape

foo 函数里的变量 t 逃逸了,和预想的一致,不解的是为什么 main 函数里的 x 也逃逸了?这是以为有些函数的参数为 interface 类型,比如 fmt.Println(a …interface{}) ,编译期间很难确定其参数的具体类型,也会发生逃逸。

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

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

相关文章

Meetily:AI会议记录,开源、免费、好用(本地AI实时转录、隐私保护一步到位!)

名人说:博观而约取,厚积而薄发。——苏轼《稼说送张琥》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 一、初识Meetily:什么是真正的智能会议助手?1. 核心优势一览2. 技术架构揭秘二、实战体验:从安装到使用的完整流程1. 系统要求2. 快速安装指南Wi…

.NET ORM开发手册:基于SqlSugar的高效数据访问全攻略

SqlSuger是一个国产,开源ORM框架,具有高性能,使用方便,功能全面的特点,支持.NET Framework和.NET Core,支持各种关系型数据库,分布式数据库,时序数据库。 官网地址:SqlS…

【论文阅读】KIMI-VL TECHNICAL REPORT

KIMI-VL TECHNICAL REPORT 原文摘要 核心模型:Kimi-VL 模型架构:基于 MoE 设计,仅激活语言解码器的 2.8B 参数(Kimi-VL-A3B),在保持高效计算的同时实现高性能。 MoE(Mixture of Experts&#xf…

项目管理学习-CSPM4(2)

1 前言 最近在学习CSPM的课程,部分内容让我受益匪浅。建议需要提升项目管理能力的同学可以通过以考促学的方式进行学习。下面整理了一部分内容和大家分享。CSPM全称China Standards Project Management,中文名为项目管理专业人员能力评价等级证书&#…

【Web前端】ECMAScript 6基础学习

ECMAScript 6 简介 ECMAScript 和 JavaScript 的关系:前者是后者的规格,后者是前者的一种实现,常场合,这两个词是可以互换的。 ECMAScript 6(以下简称 ES6)是 JavaScript 语言的标准,在 2015 年 6 月发布…

基于Python的全卷积网络(FCN)实现路径损耗预测

以下是一份详细的基于Python的全卷积网络(FCN)实现路径损耗预测的技术文档。本方案包含理论基础、数据生成、模型构建、训练优化及可视化分析,代码实现约6000字。 基于全卷积网络的无线信道路径损耗预测系统 目录 问题背景与需求分析系统架构设计合成数据生成方法全卷积网络…

AI数字人一体机和智慧屏方案:开启智能交互新纪元

在当今这个信息化飞速发展的时代,AI技术正以前所未有的速度改变着我们的生活方式和工作模式。特别是在人机交互领域,AI数字人的出现不仅极大地丰富了用户体验,也为各行各业提供了前所未有的创新解决方案。本文将重点介绍由广州深声科技有限公…

练习实践--deepseek的使用环境搭建回顾--火山方舟

快速回顾 有更多第三方可以提供免费的大模型体验服务,比如硅基流动/火山方舟,通过选择指定模型,生成模型id和自己的API-KEY这两个信息,可以在第三方集成ai工具,如cherry studio上使用; 参考来源 来自阮一…

Adminer 连接mssql sqlserver

第一步 docker-compose.yml adminer部分: version: 3.8 services: adminer: image: adminer:latest container_name: adminer restart: unless-stopped volumes: - ./freetds/freetds.conf:/etc/freetds.conf:rw # 确保 :rw 可读写 co…

JWT令牌详解及Java中的使用实战

JWT令牌详解及Java中的使用实战 摘要 本文将深入解析**JWT(JSON Web Token)**的核心概念,通过图文并茂的方式详解其工作原理,并手把手教你在Java中实现JWT的生成、验证与解析。无论你是认证授权新手还是想巩固知识的老手&#x…

晶圆隐裂检测提高半导体行业效率

半导体行业是现代制造业的核心基石,被誉为“工业的粮食”,而晶圆是半导体制造的核心基板,其质量直接决定芯片的性能、良率和可靠性。晶圆隐裂检测是保障半导体良率和可靠性的关键环节。 晶圆检测 通过合理搭配工业相机与光学系统&#xff0c…

Java 的 ReentrantLock

Java中的ReentrantLock是java.util.concurrent.locks包下提供的一个可重入互斥锁,用于替代synchronized关键字实现更灵活的线程同步。以下是其核心特性和使用方法的详细说明: 核心特性 可重入性 同一个线程可以重复获取同一个锁(锁的持有计数…

达梦数据库-学习-23-获取执行计划的N种方法

目录 一、环境信息 二、说点什么 三、测试数据生成 四、测试语句 五、获取执行计划方法 1、EXPLAIN (1)样例 (2)优势 (3)劣势 2、ET (1)开启参数 (2&#xff…

20200201工作笔记常用命令要整理

工作笔记常用命令: 1.repo常用命令: repo sync -c -j10 2. 常用adb命令 错误: error: device unauthorized. This adbds $ADB_VENDOR_KEYS is not set; try adb kill-server if that seems wrong. Otherwise check for a confirmation dialog on your d…

PET,Prompt Tuning,P Tuning,Lora,Qlora 大模型微调的简介

概览 到2025年,虽然PET(Pattern-Exploiting Training)和Prompt Tuning在学术界仍有探讨,但在工业和生产环境中它们已基本被LoRA/QLoRA等参数高效微调(PEFT)方法取代 。LoRA因其实现简单、推理零开销&#…

9种方法,一键美化Python图表

Matplotlib、Seaborn默认参数不好看,美化需要大量代码。 本次分享9种方法,一键美化图表,看看那个是你的菜。 1 Matplotlib style sheets Matplotlib内置多类style sheets, 一行代码使用, plt.style.use(Solarize_Li…

在STM32上配置图像处理库

在STM32上配置并使用简单的图像滤波库(以实现均值滤波为例,不依赖复杂的大型图像处理库,方便理解和在资源有限的STM32上运行)为例,给出代码示例,使用STM32CubeIDE开发环境和HAL库,假设已经初始化好了相关GPIO和DMA(如果有图像数据传输需求),并且图像数据存储在一个二…

Android四大组件学习总结

​1. Activity 启动模式问题​ ​面试官​: “我看你项目里用了 SingleTask 模式,能具体说说为什么用它吗?如果从 Activity A(SingleTask)跳转到 B(Standard),再返回 A,…

基于SamOutV8的序列生成模型实现与分析

项目概述 本项目实现了基于SamOutV8架构的序列生成模型,核心组件包括MaxStateSuper、FeedForward和DecoderLayer等模块。通过结合自注意力机制与状态编码策略,该模型在处理长序列时表现出良好的性能。 核心组件解析 1. MaxStateSuper(状态编…

从脑电图和大脑记录中学习稳健的深度视觉表征

从脑电图和大脑记录中学习稳健的深度视觉表征 印度,印度,印度,印度大脑实验室,印度 例如,达拉普,克普拉萨德,山,山,新的。ac .在 摘要 解码人类大脑一直是新机器人科学家…