• 为何要做逃逸分析


    逃逸分析是golang编译器分析一个对象到底应该放到堆内存上,还是栈内存上(引用了他人的文章)

    为何要做逃逸分析

    因为对一个程序来说,使用栈内存还是堆内存他们的效率差别很大。
    栈内存:

    1. 操作系统管理内存的分配和释放,不用golang的垃圾回收操心
    2. 内存的存储结构类似于数据结构中的栈,读写位置都在栈顶。
    3. 栈内存可有效放入cpu的缓存,这样读写效率就比实际内存中少1-2个数量级的时间。
    4. 缺点就是不会太大(linux 系统可以使用ulimit -s查看,目前我的实验环境是ubuntu20.04,栈内存的最大值是8M)
    5. 一般局部变量,函数参数都会放在栈内存中(罗嗦一句:为什么这里使用一般呢,在C语言中,我可以告诉你是一定,但是golang里面,如果你返回了局部变量的地址,这个时候局部变量就会放在堆了,因为这个局部变量逃出了函数的作用域)。

    堆内存:

    1. 需要程序自己进行管理,可以是手动申请释放,如C/C++;也可以是语言提供的垃圾回收机制释放的
    2. 堆内存的存储结构和数据结构中的堆没有半毛钱关系,它是用链表结构实现的
    3. 堆内存申请还要去内存中寻找,还会产生内存碎片
    4. 堆内存的优点就是申请内存大小可以很大-----64位系统:理论最大能支持2147483648GB,实际上取决于你用的系统上没有被使用的的内存大小 ;32位系统:最大2^32 ,一个进程能够使用的一共4GB的内存,还需要留一部分给栈内存,代码段,数据段,实际能申请的最大约3.5G
    5. 未知大小的变量,未知作用域的变量等。

    根据堆和栈各自的优缺点后,逃逸分析存在的目的如下:

    1. 区分对象使用堆栈内存,栈内存的对象不管了,减轻垃圾回收(gc)的压力
    2. 减少内存碎片的产生。
    3. 减轻分配堆内存的开销,提高程序的运行速度。

    如何确定是否逃逸

    在Go中通过逃逸分析日志来确定变量是否逃逸,开启逃逸分析日志:
    go run -gcflags '-m -l' stack.go # stack.go 来自于上一篇栈结构golang的实现

    # command-line-arguments
    ./stack.go:17:3: &Stack literal escapes to heap
    ./stack.go:15:18: make([]int, size) escapes to heap
    ./stack.go:40:7: (*Stack).IsFull s does not escape
    ./stack.go:21:7: (*Stack).Push s does not escape
    ./stack.go:47:7: (*Stack).IsEmpty s does not escape
    ./stack.go:30:7: (*Stack).Pop s does not escape
    ./stack.go:56:13: main ... argument does not escape
    ./stack.go:56:13: .autotmp_1 escapes to heap
    ./stack.go:56:13: .autotmp_2 escapes to heap
    ./stack.go:62:13: main ... argument does not escape
    ./stack.go:62:13: .autotmp_3 escapes to heap
    ./stack.go:62:13: .autotmp_4 escapes to heap
    ./stack.go:63:13: main ... argument does not escape
    ./stack.go:63:13: .autotmp_5 escapes to heap
    ./stack.go:63:13: .autotmp_6 escapes to heap
    ./stack.go:64:13: main ... argument does not escape
    ./stack.go:64:13: .autotmp_7 escapes to heap
    ./stack.go:64:13: .autotmp_8 escapes to heap
    false 0
    true 3
    true 2
    true 1
    

    其中escapes to heap 表示分配到了堆内存上。
    其中does not escape 表示分配到了栈内存上。



    作者:郭青耀
    链接:https://www.jianshu.com/p/a4b2296fc29b
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    [图解算法] 最短路径算法之 “Dijikstra”
    [前端随笔][CSS] 伪类的应用
    [前端随笔][JavaScript] 实现原生的事件监听<Vue原理>
    [图解算法] 最短路径算法之 “Floyd”
    [前端随笔][JavaScript][自制数据可视化] “中国地图”
    [前端随笔][JavaScript] 懒加载的实现(上划一次加载一部分)
    [前端随笔][CSS] 制作一个加载动画 即帖即用
    ThinkPHP下隐藏index.php以及URL伪静态
    PHP基础语法3
    PHP基础语法2
  • 原文地址:https://www.cnblogs.com/jackey2015/p/13143249.html
Copyright © 2020-2023  润新知