Golang语言中的逃逸分析详解
admin
2024-03-18 15:41:10

1.什么是逃逸分析

说到逃逸分析我们先聊一聊C/C++中的malloc和new,他们都可以从堆上分配到一块内存,该内存的销毁都是需要程序员来销毁,一不小心就可能发生内存泄漏,这是很危险的。首先我们来看一下他们有什么区别:
(1)malloc:是memory(内存)和allocate(分配)缩写结合:

  • 从堆上分配内存,堆是操作系统的术语;
  • 与new不一样,malloc仅仅分配内存,free仅仅是回收内存(与malloc对应)

(2)new从自由存储区上分配内存(自由存储区是C/C++基于new操作符的一个抽象概念,凡是通过new操作符进行内存申请该内存为自由存储区);

  • new能在堆上动态分配内存,也可以是静态存储区,取决于operator new 在哪里new
  • 使用new先调用malloc分配内存空间,再调用对象的构造函数;delete会调用对象的析构函数,再调用free回收内存。
    在Go语言中程序员基本上不需要再担心内存泄漏。虽然Go也有内建函数new,但是调用new函数得到的内存不一定在堆上,还有可能在栈上。这是因为go语言的堆和栈被模糊化了,这一切都是有Go编译器在后台完成的。(具体C/C++堆栈与Go有何不同可参考我的另一篇博客:Go与C/C++中的堆和栈比较
    聊了这么多,那么逃逸分析是如何定义的呢?
    在编译原理中,分析指针动态范围的方法被称之为逃逸分析。通俗来讲,当一个对象的指针被多个方法或线程引用时,则称这个指针发生了逃逸。逃逸分析决定一个变量是分配在堆上还是分配在栈上。如果编译器发现这块内存在退出函数后就没有使用了,那就分配到栈上

2.逃逸分析的作用

  • 按需分配,编译器经过逃逸分析后发现函数退出后这块内存没有再用,那么分配到栈上。反之分配到堆上,我们都知道栈上的内存分配比堆上快很多。有了逃逸分析,在无形中缩短了程序运行时间
  • 减小系统开销,堆不像栈可以自动清理,如果变量都分配到堆上,会频繁的进行垃圾回收,而垃圾回收会占用比较大的系统开销。
  • 减少内存碎片生成,堆内存分配比较慢,而且会形成内存碎片,栈内存会自动释放不会形成内存碎片;
  • 减少垃圾回收的压力,通过逃逸分析之后,可尽量把不需要分配到堆上的内存分配到栈上,堆上的变量少了,会减轻堆内存的开销,同事也会减少垃圾回收(Garbage Collection,GC)的压力,提高程序的运行速度。

3.逃逸分析是怎样形成的

逃逸分析基本原则:编译器分析代码的特征和代码的声明周期,如果一个函数返回堆一个变量的引用,那么这个变量就会发生逃逸。 简单的来说编译器会根据变量时候被外部引用来决定是否逃逸:

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

4.如何确定是否发生了逃逸

这个问题我在其他文章有详细说明,参考地址:Golang语言中如何确定是否发生逃逸

相关内容

热门资讯

优质广货卖爆了 消费盛会彰显“... 统筹/孙晶文/羊城晚报全媒体记者 杭莹 沈钊 扶贝贝 张闻图/羊城晚报全媒体记者 钟振彬 邓鼎园“流...
10派10元!A股龙头,大手笔... 重要新闻提示央行:下调各类结构性货币政策工具利率0.25个百分点;降准降息今年还有一定空间利欧股份:...
卡尼来访推动中加关系全面转圜 ... 时隔8年,加拿大总理的专机终于降落在了北京。据新华社报道,应中方邀请,加拿大总理马克·卡尼于1月14...
驶入阿拉木图:满街的中国品牌,... “一到阿拉木图,很快就能看到很多中国品牌,从汽车品牌,到家电、电子产品、手机品牌等等。”Yandex...
当“绣花精神”遇见AI:数字绣... 文/羊城晚报全媒体记者 程行欢 汪海晏 董鹏程图/唐德荣 陈明谦 潘嘉焌从一针一线的精细功夫,到算法...