【Golang】什么是内存逃逸?

这篇具有很好参考价值的文章主要介绍了【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的垃圾回收器会自动管理内存。当然,使用栈上的内存更具有性能,如果你特别在意这种性能的话,以下是一些避免内存逃逸的方法文章来源地址https://www.toymoban.com/news/detail-673205.html

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

到了这里,关于【Golang】什么是内存逃逸?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Golang vs Rust ——服务端编程应该选择哪种语言

    为服务端编程选择一种语言应该基于你的长期目标和项目的要求,因此,盲目地问我应该雇用 Go 开发人员还是应该选择 Rust 进行开发并不能帮助你解决问题。 然而,如果你发现自己陷入了困境,那么这篇文章将为你解惑。下面让我们开始吧。 Go 是一种静态类型的、AOT 编译的

    2024年02月02日
    浏览(57)
  • golang 如何防止内存逃逸

    在Go语言中,内存逃逸是指在函数中分配的变量在函数结束后仍然被引用,从而导致变量的生命周期延长,被分配在堆上而不是栈上。防止内存逃逸有助于提高程序的性能,因为栈上分配的内存可以更快地被回收。 以下是一些防止内存逃逸的方法: 避免返回局部变量的指针:

    2024年02月21日
    浏览(34)
  • 高频golang面试题:简单聊聊内存逃逸?

    知道golang的内存逃逸吗?什么情况下会发生内存逃逸? golang程序变量会携带有一组校验数据,用来证明它的整个生命周期是否在运行时完全可知。如果变量通过了这些校验,它就可以在栈上分配。否则就说它 逃逸 了,必须在堆上分配。 能引起变量逃逸到堆上的典型情况:

    2024年02月09日
    浏览(41)
  • 【Golang星辰图】数据管理利器:Go编程语言中的数据库和搜索引擎综合指南

    Go编程语言是一种强大、类型安全且高效的编程语言,它在处理数据库和搜索引擎方面有着广泛的应用。本篇文章将详细介绍几个Go编程语言中常用的数据库和全文搜索引擎,包括Go-bleve、Go-pgx、Go-leveldb/leveldb、Go-xorm、Go-mysql-driver和Go-bbolt/bbolt。对于每个工具,我们将介绍其功

    2024年03月26日
    浏览(67)
  • 100天精通Golang(基础入门篇)——第15天:深入解析Go语言中函数的应用:从基础到进阶,助您精通函数编程!(进阶)

    🌷 博主 libin9iOak带您 Go to Golang Language.✨ 🦄 个人主页——libin9iOak的博客🎐 🐳 《面试题大全》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 🌊 《IDEA开发秘籍》学会IDEA常用操作,工作效率翻倍~💐 🪁 希望本文能够给您带来一定的帮助🌸文章粗浅,敬请批

    2024年02月12日
    浏览(67)
  • C语言编程—内存管理

    C语言中的动态内存管理。C语言为内存的分配和管理提供了几个函数。这些函数可以在 stdlib.h 头文件中找到。 在C语言中,内存是通过指针变量来管理的。指针是一个变量,它存储了一个内存地址,这个内存地址可以指向任何数据类型的变量,包括整数、浮点数、字符和数组

    2024年02月11日
    浏览(42)
  • C语言嵌入式系统编程注意事项之内存操作

    在嵌入式系统的编程中,常常要求在特定的内存单元读写内容,汇编有对应的MOV指令,而除C/C++以外的其它编程语言基本没有直接访问绝对地址的能力 数据指针 在嵌入式系统的编程中,常常要求在特定的内存单元读写内容,汇编有对应的MOV指令,而除C/C++以外的其它编程语言

    2024年02月09日
    浏览(63)
  • C# 编程语言有什么特点?

    在开始前我有一些资料,是我根据网友给的问题精心整理了一份「C#的资料从专业入门到高级教程」, 点个关注在评论区回复“888”之后私信回复“888”,全部无偿共享给大家!!!C#(C Sharp)是一种由Microsoft开发的多范式编程语言,最初发布于2000年。以下是C#编程语言的一

    2024年01月22日
    浏览(56)
  • THRUST:一个开源的、面向异构系统的并行编程语言:编程模型主要包括:数据并行性、任务并行性、内存管理、内存访问控制、原子操作、同步机制、错误处理机制、混合编程模型、运行时系统等

    作者:禅与计算机程序设计艺术 https://github.com/NVIDIA/thrust 2021年8月,当代科技巨头Facebook宣布其开发了名为THRUST的高性能计算语言,可用于在设备、集群和云环境中进行并行计算。它具有“易于学习”、“简单易用”等特征,正在逐步取代C++、CUDA、OpenCL等传统编程模型,成为

    2024年02月07日
    浏览(48)
  • 什么是硬件编程,C 语言如何进行硬件编程?C 语言常用的操作系统有哪些?

    硬件编程是指使用编程语言与硬件交互,控制硬件设备的行为和功能。其中,C语言是一种广泛用于硬件编程的高级编程语言。 C语言通过直接操作内存来进行硬件编程。它提供了一些特殊的和库函数,使得开发者可以直接访问和操作硬件设备的寄存器、端口和外设等。

    2024年02月15日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包