当前位置: 首页 > news >正文

【Golang】什么是内存逃逸?

文章目录

  • 要从C/C++谈起
  • Golang的内存逃逸


要从C/C++谈起

在C/C++中,局部变量被分配到栈区,一旦当前函数执行完毕,局部变量占用的内存也将被释放,因此以下代码无法将数组的内容传递出去。

int *getArray() {int array[7] = {1, 2, 3, 4, 5, 6, 7};return array;
}int main() {int *array = getArray();for (int i = 0; i < 7; i++) {cout << array[i] << ", ";}return 0;
}

因为,当getArray()执行完毕后,array数组的内存就被释放了,返回的array指针是一个野指针。再访问这个指针得到的是不确定的、无意义的数据。

解决办法是利用动态内存分配,使用new关键字申请一个堆区的内存(C使用malloc,C++使用new),将以上代码中定义数组的行替换为:

int *array = new int[7]{1, 2, 3, 4, 5, 6, 7}; // tips:这种初始化写法是C++11的特性

这样就可以把getArray()中创建的数组传递出去,使用完毕后,编写delete[] array;释放内存。

Golang的内存逃逸

不同于C/C++,Golang的内存分配是完全由编译器自动管理的,开发者无法干预。

在Golang中,内存逃逸指的是在函数中分配的局部变量或对象,由于其生命周期需要延长或在函数外部继续使用,导致编译器将其分配到堆区而不是栈区的情况。这种情况下,变量或对象的生命周期超出了原本的作用域,需要在堆上分配内存以保证数据的有效性。

Go编译器在编译时,会尽量将变量分配到栈区,以提高内存的访问速度。但是,如果编译器无法确定变量的声明周期是否会超出作用域,就会将其分配到堆上,以确保数据访问的有效性。这种情况就被称为内存逃逸。简单说,就是局部变量被分配到了堆区。

当函数外部对指针没有引用时,优先分配在栈上。以下是一些触发内存逃逸的情况:

  1. 在函数中返回指针:如果在函数中创建一个局部变量,然后返回它的指针,那么这个变量很可能会逃逸到堆上,因为它需要在函数退出后仍然可访问。
  2. 在函数中开启 goroutine:如果在函数内部开启了一个 goroutine,并将局部变量传递给这个 goroutine,这个变量可能会逃逸,因为 goroutine 可能在函数退出后继续访问该变量。
  3. 变量被闭包使用:如果一个闭包引用了外部函数的局部变量,这个变量也可能会逃逸到堆上,因为闭包可能会在函数退出后继续存在。
  4. 变量占用空间太大:如果一个局部变量很大,超过了栈的大小限制,编译器可能会将其分配到堆上,以避免栈溢出。

"内存逃逸"听起来好像"有什么东西跑掉了"一样,乍一听给人一种不好的信号。实际上它并不是太值得关注的问题。

内存逃逸通常不会引发大问题,因为Go的垃圾回收器会自动管理内存。当然,使用栈上的内存更具有性能,如果你特别在意这种性能的话,以下是一些避免内存逃逸的方法

  1. 避免闭包: 闭包可能导致变量的生命周期延长,从而导致内存逃逸。尽量避免在闭包中使用外部变量。
  2. 避免返回指针或引用: 返回指向局部变量的指针或引用会导致内存逃逸。(Go有三个引用类型:slice,map,chan)
  3. 返回数组而不是切片(slice):数组是值类型的,切片是引用类型的。
  4. 使用值类型的接收器(receiver): 当定义方法时,如果不需要修改接收器的状态,尽量使用值类型的接收器而不是指针接收器,可以减少内存逃逸的可能性。
  5. 使用编译器分析工具:可以使用go build -gcflags="-m"命令来触发编译器的逃逸分析报告。这会在编译过程中输出逃逸分析的结果,帮助我们了解哪些变量逃逸到了堆上。

相关文章:

【Golang】什么是内存逃逸?

文章目录 要从C/C谈起Golang的内存逃逸 要从C/C谈起 在C/C中&#xff0c;局部变量被分配到栈区&#xff0c;一旦当前函数执行完毕&#xff0c;局部变量占用的内存也将被释放&#xff0c;因此以下代码无法将数组的内容传递出去。 int *getArray() {int array[7] {1, 2, 3, 4,…...

MVC OR DDD

MVC OR DDD 说明&#xff1a;这篇是标题党&#xff0c;不包含相关概念说明 前段时间跟随师兄学习了解了DDD领域驱动模型&#xff0c;觉得这个思想更好&#xff0c;进行下面解析和学习方面的思考和实践&#xff0c;觉得很好&#xff0c;耐心读下去。希望对您有所帮助。 首先&am…...

前端面试:【TypeScript】静态类型检查与编译时类型检查

TypeScript是一种由Microsoft开发的编程语言&#xff0c;它在JavaScript的基础上添加了强大的静态类型系统。在本文中&#xff0c;我们将深入探讨TypeScript的静态类型检查和编译时类型检查&#xff0c;以及它们如何提高代码的可靠性和可维护性。 1. 静态类型检查&#xff08;S…...

Qt中设置QListWidget滑动条滚动速度

QListWidget继承QListView控件&#xff0c;Qt帮助文档中说 QAbstractItemView::ScrollPerPixel 和QAbstractItemView::ScrollPerItem分别可以实现按item滚动和像数点滚动&#xff0c;但是好像都没效果。还有就是说通过创建QScrollBar有用&#xff0c;但是也没效果。 亲测还是这…...

STM32的lorawan协议栈

LoRa 是LPWAN通信技术中的一种&#xff0c;是美国Semtech公司采用和推广的一种基于扩频技术的超远距离无线传输方案。这一方案改变了以往关于传输距离与功耗的折衷考虑方式为用户提供一种简单的能实现远距离、长电池寿命、大容量的系统&#xff0c;进而扩展传感网络。目前&…...

IC芯片 trustzone学习

搭建Airplay TA环境需要在IC的TrustZone中进行。TrustZone是一种安全技术&#xff0c;用于隔离安全和非安全环境&#xff0c;并保护敏感文件。在TrustZone中&#xff0c;我们需要编写一个叫做TA&#xff08;Trusted Application&#xff09;的应用程序来控制这些私密文档。 &am…...

Day19-异步请求-axios文件上传

Day19-异步请求 什么是同步请求当前浏览器刷新或者改变浏览器地址栏地址才能发送请求,这种请求称为同步请求 什么是异步请求当我们发送请求时,浏览器不会刷新,浏览器地址栏也不会变化,这种请求称为异步请求异步请求用到的前端技术: ajax 或 axios一 封装Ajax /*** 编写ajax函…...

从零学算法79

79.给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 单词必须按照字母顺序&#xff0c;通过相邻的单元格内的字母构成&#xff0c;其中“相邻”单元格是那些水平相邻或垂直…...

ctfshow-web-红包题第六弹

0x00 前言 CTF 加解密合集CTF Web合集 0x01 题目 0x02 Write Up 首先跑一下字典&#xff0c;这里用的dirmap,可以看到有一个web.zip 下载下来之后发现是一个网站备份&#xff0c;备份的是check.php.bak 然后接着看&#xff0c;可以看到这里不太可能是sql注入&#xff0c;有…...

蓝蓝设计UI设计公司-界面设计与开发案例

天津航天中为项目 中国南方电网十二个软件交互优化和界面设计 图标设计 | 交互设计 | 界面设计 天津航天中为数据系统科技有限公司是航天503所控股的专业化公司&#xff0c;坐落于天津滨海新区航天技术产业园&#xff0c;是航天五院家入住天津未来科技城的军民融合型企业&…...

IDEA 配置注释模板

目录 一、配置类模板注释 二、配置方法注释 一、配置类模板注释 打开IDEA&#xff0c;打开settings(快捷键&#xff1a;Ctrl Alt s)&#xff0c;选择Editor&#xff0c;找到File and Code Templates&#xff0c;设置需要配置注释的文件类型&#xff0c;如下图所示&#xf…...

Kuka机器人设计通用码垛程序

假设需要一个码垛程序, 从输送线抓到托盘, 托盘每层4个, 需要码5层, 可以用以下程序架构设计: 1, 再config中定义层数cengshu , 每层码垛的个数(码垛的次数)cishu , 每层的高度levelHeight , 码垛放置点的集合putPoint[,] ,预放点1集合prePut1[,], 预放点2集合prePut2[,] DEC…...

pandas由入门到精通-数据清洗-扩展数据类型

pandas-02-数据清洗&预处理 扩展数据类型1. 传统数据类型缺点2. 扩展的数据类型3. 如何转换类型文中用S代指Series,用Df代指DataFrame 数据清洗是处理大型复杂情况数据必不可少的步骤,这里总结一些数据清洗的常用方法:包括缺失值、重复值、异常值处理,数据类型统计,分…...

深入理解 Vue Router:构建可靠的前端路由系统

目录 01-什么是前端路由以及路由两种模式实现原理02-路由的基本搭建与嵌套路由模式03-动态路由模式与编程式路由模式04-命名路由与命名视图与路由元信息05-路由传递参数的多种方式及应用场景06-详解route对象与router对象07-路由守卫详解及应用场景 01-什么是前端路由以及路由两…...

Mysql B+数索引结构

一、B树和B树区别 二、 B 树形成过程 三、页分裂过程 3.1 页分裂过程实例 3.1.1 原有数据1、3、5形成如下数据页 3.1.2 先新插入数据4&#xff0c;因为 页10 最多只能放3条记录所以我们不得不再分配一个新页&#xff1a; 新分配的数据页编号可能并不是连续的&#xff0c;也…...

在window上配置NASM

NASM是支持x86、x64架构CPU的汇编器(汇编软件)&#xff1b;NASM也支持大量的文件格式&#xff0c;包括Linux&#xff0c;*BSD&#xff0c;a.out&#xff0c;ELF&#xff0c;COFF&#xff0c;Mach−O&#xff0c;Microsoft 16−bit OBJ&#xff0c;Win32以及Win64&#xff0c;同…...

用QT实现MVP模式

近些天用qt 作项目,遇到参数界面.偷闲写个mvp模式示例. mvp模式重要的有两点 1 低耦合: 界面与后端数据类,不直接引用,可方便替换. 2 形成界面驱动-界面更新的闭环.:通过函数指针类技术,让数据自动回流. MVP (Model-View-Presenter) 视图&#xff08;View&#xff09;: 接…...

(2023)Linux安装pytorch并使用pycharm远程编译运行

&#xff08;2023&#xff09;Linux安装pytorch并使用pycharm远程编译运行 安装miniconda 这部分参考我这篇博客的前半部分Linux服务器上通过miniconda安装R&#xff08;2022&#xff09;_miniconda 安装r_Dream of Grass的博客-CSDN博客 创建环境 创建一个叫pytorch的环境…...

poi带表头多sheet导出

导出工具类 package com.hieasy.comm.core.excel;import com.hieasy.comm.core.excel.fragment.ExcelFragment; import com.hieasy.comm.core.utils.mine.MineDateUtil; import org.apache.poi.hssf.usermodel.*; import org.apache.poi.ss.usermodel.*; import org.apache.po…...

RedisDesktopManager(redis客户端,可输入用户名密码)

RedisDesktopManager&#xff08;redis客户端&#xff0c;可输入用户名密码&#xff09; Redis桌面管理器&#xff08;又名RDM&#xff09; - 是一个用于Windows&#xff0c;Linux和MacOS的快速开源Redis数据库管理应用程序。可以使用url连接或账号密码。 redis设置账号密码后…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

Android Wi-Fi 连接失败日志分析

1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分&#xff1a; 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析&#xff1a; CTR…...

【kafka】Golang实现分布式Masscan任务调度系统

要求&#xff1a; 输出两个程序&#xff0c;一个命令行程序&#xff08;命令行参数用flag&#xff09;和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽&#xff0c;然后将消息推送到kafka里面。 服务端程序&#xff1a; 从kafka消费者接收…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

学校招生小程序源码介绍

基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码&#xff0c;专为学校招生场景量身打造&#xff0c;功能实用且操作便捷。 从技术架构来看&#xff0c;ThinkPHP提供稳定可靠的后台服务&#xff0c;FastAdmin加速开发流程&#xff0c;UniApp则保障小程序在多端有良好的兼…...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南

&#x1f680; C extern 关键字深度解析&#xff1a;跨文件编程的终极指南 &#x1f4c5; 更新时间&#xff1a;2025年6月5日 &#x1f3f7;️ 标签&#xff1a;C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言&#x1f525;一、extern 是什么&#xff1f;&…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...