美文网首页工作生活
GO语言变量逃逸分析

GO语言变量逃逸分析

作者: 木工007 | 来源:发表于2019-07-09 20:01 被阅读0次

引言

        内存管理的灵活性是让C/C++程序猿们又爱又恨的东西,比如malloc或new一块内存我可以整个进程使用。但是,如果这块内存在某个函数中new了,但是暂时不能释放那就是悲剧开始了。鬼知道何时释放合适及是不是我还记得我new过它。所以后来很多语言都限制了内存管理或者优化了内存管理机制,添加gc机制来“辅助”程序猿们编程。变量分配在堆上还是栈上不是由是否new/malloc决定,而是通过编译器的“逃逸分析”来决定。

什么是逃逸分析

        在编译程序优化理论中,逃逸分析是一种确定指针动态范围的方法——分析在程序的哪些地方可以访问到指针。也是就是说逃逸分析是解决指针作用范围的编译优化方法。编程中常见的两种逃逸情景:

        1,函数中局部对象指针被返回(不确定被谁访问)

         2,对象指针被多个子程序(如线程 协程)共享使用

为什么要做逃逸分析

        开始我们提到go语言中对象内存的分配不是由语言运算符或函数决定,而是通过逃逸分析来决定。为什么要这么干呢?其实说到底还是为了优化程序。函数中生成一个新对象:

1,如果分配到栈上,待函数返回资源就被回收了

2,如果分配到堆上,函数返回后交给gc来管理该对象资源

栈资源的分配及回收速度比堆要快,所以逃逸分析最大的好处应该是减少了GC的压力。

逃逸分析的场景

指针逃逸

典型的逃逸case,函数返回局部变量的指针。

运行:go build -gcflags "-m -l" escap01.go

-m 可以用多个来打印更详细的信息,-l去掉inline信息。局部变量a被分配到堆上。

栈空间不足逃逸

当对象大小超过的栈帧大小时(详见go内存分配),变量对象发生逃逸被分配到堆上。

当s的容量足够大时,s逃逸到堆上。t容量较小分配到栈上

闭包引用逃逸

Fibonacci()函数返回一个函数变量赋值给f,f就成了一个闭包。闭包f保存了a b的地址引用,所以每次调用f()后ab的值发生变化。ab发生逃逸。

但如果直接调用Fibonacci(),则ab都是独立的局部变量。

动态类型逃逸

当对象不确定大小或者被作为不确定大小的参数时发生逃逸。

t的大小是个变量所以会逃逸到堆上。size作为interface{}参数逃逸到堆上。

切片或map赋值

在给切片或者map赋值对象指针(与对象共享内存地址时),对象会逃逸到堆上。但赋值对象值或者返回对象值切片是不会发生逃逸的。

    变量逃逸情况还有很多,暂时学习整理这些。程序性能优化是一个很重要的方向,对于现在还在完善的go编译器,我们需要不断总结现有缺陷,尽量在编码时注意潜在的问题,不要把优化都留给编译器(也不可能都留给它,因为我也不知道要优化什么 0-0 )。

总结

    逃逸分析是编译器在静态编译的时候,分析对象的生命周期及引用情况来决定对象内存分配到堆上还是栈上,由于栈内存分配较堆快且栈内存回收较快(无需gc),编译器以此来优化程序性能。

参考

逃逸分析

Golang内存分配逃逸分析

相关文章

  • GO语言变量逃逸分析

    引言 内存管理的灵活性是让C/C++程序猿们又爱又恨的东西,比如malloc或new一块内存我可以整个进程使用。但...

  • go 逃逸分析

    go 逃逸分析 什么是逃逸分析 逃逸分析决定一个变量是分配在堆上还是分配在栈上 原理 逃逸分析这种“骚操作”把变量...

  • golang内存逃逸

    一篇很好的博客: Go 语言机制之栈与指针 Go 语言机制之逃逸分析 Go 语言机制之内存剖析 Go 语言机制之数...

  • 聊一聊go的内存逃逸分析

    什么是内存逃逸分析 内存逃逸分析是go的编译器在编译期间,根据变量的类型和作用域,确定变量是堆上还是栈上 简单说就...

  • go语言 逃逸分析

    go语言逃逸分析 任何时候,一个值被分享到函数栈帧范围之外,它都会在堆上被重新分配,说道这个问题了,我们就谈谈帧边...

  • Go语言逃逸分析

    本贴转自https://www.cnblogs.com/itbsl/p/10476674.html[https:/...

  • go-内存机制(1)

    逃逸分析 堆与栈 在go语言中,变量可以存储在栈或者堆之上。如果变量存储在栈之上,那么当这个栈被清理时,对应的栈内...

  • Golang的入门教程(四)

    1: 变量逃逸 堆和栈各有优缺点,该怎么在变成中处理这个问题呢?Go语言将这个过程整合到编译器中,命名为"变量逃逸...

  • golang方法返回局部变量指针

    go的方法可以直接返回局部变量的指针,这主要依赖go是有runtime的语言,编译器在发现有变量可以逃逸出去的时候...

  • 【Go语言基础2.1】变量逃逸

      编译器会优先将局部变量存放在栈中,便于及时清理,但是如果存放在栈上的变量被清理了,但是函数其他地方还存在对它的...

网友评论

    本文标题:GO语言变量逃逸分析

    本文链接:https://www.haomeiwen.com/subject/lpqhhctx.html