Golang语言中的逃逸分析详解-创新互联
1.什么是逃逸分析
标题名称:Golang语言中的逃逸分析详解-创新互联
网页地址:http://hbruida.cn/article/csjhdg.html
说到逃逸分析我们先聊一聊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++中的堆和栈比较
聊了这么多,那么逃逸分析是如何定义的呢?
在编译原理中,分析指针动态范围的方法被称之为逃逸分析。通俗来讲,当一个对象的指针被多个方法或线程引用时,则称这个指针发生了逃逸。逃逸分析决定一个变量是分配在堆上还是分配在栈上。如果编译器发现这块内存在退出函数后就没有使用了,那就分配到栈上
- 按需分配,编译器经过逃逸分析后发现函数退出后这块内存没有再用,那么分配到栈上。反之分配到堆上,我们都知道栈上的内存分配比堆上快很多。有了逃逸分析,在无形中缩短了程序运行时间
- 减小系统开销,堆不像栈可以自动清理,如果变量都分配到堆上,会频繁的进行垃圾回收,而垃圾回收会占用比较大的系统开销。
- 减少内存碎片生成,堆内存分配比较慢,而且会形成内存碎片,栈内存会自动释放不会形成内存碎片;
- 减少垃圾回收的压力,通过逃逸分析之后,可尽量把不需要分配到堆上的内存分配到栈上,堆上的变量少了,会减轻堆内存的开销,同事也会减少垃圾回收(Garbage Collection,GC)的压力,提高程序的运行速度。
逃逸分析基本原则:编译器分析代码的特征和代码的声明周期,如果一个函数返回堆一个变量的引用,那么这个变量就会发生逃逸。 简单的来说编译器会根据变量时候被外部引用来决定是否逃逸:
- 如果变量在函数外部没有被引用,则优先分配到栈上
- 如果变量在函数外部存在引用,则必定分配在堆上
针对第一条,放在堆上的情形:定义一个很大的数组,需要申请的内存过大,超过了栈的存储能力。
这个问题我在其他文章有详细说明,参考地址:Golang语言中如何确定是否发生逃逸
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
标题名称:Golang语言中的逃逸分析详解-创新互联
网页地址:http://hbruida.cn/article/csjhdg.html