Go语言内存管理详解-学习笔记

1 自动内存管理

1.1 相关概念

  • Mutator:业务线程,分配新对象,修改对象指向关系
  • Collector:GC线程,找到存活对象,回收死亡对象的内存空间
  • Serial GC:只有一个collector(需要暂停)
  • Parallel GC:支持多个collectors同时回收的GC算法(需要暂停)
  • Concurrent GC:mutator(s)和collector(s)可以同时执行(不需要暂停)

1.2 追踪垃圾回收

        对象被回收的条件:指针指向关系不可达的对象

        标记可达对象,清理所有不可达对象

1.3 分代GC

        很多对象在分配出来后很快就不再使用了

        对年轻和老年的对象,制定不同的GC策略,降低整体内存管理的开销

1.4 引用计数

        存活条件:当且仅当引用数大于0

2 Go内存管理及优化

2.1 Go内存分配

        提前将内存分块。首先向OS申请一大块内存,然后将内存划分为若干个大块,再将大块划分成特定大小的小块用于对象分配,有的大块用来分配不包含指针的对象(GC不需要扫描),有的大块分配包含指针的对象(GC需要扫描)。

        缓存策略。每个P包含一个缓存用于为P上的G分配对象,如果缓存分配完毕,向下一级缓存申请未分配的大块。

2.2 Go内存管理优化

        对象分配中,小对象占比较高

2.3 优化方案:Balanced GC

        每个G都绑定一大块内存,称作GAB,用于无指针小对象分配。使用三个指针维护GAB:base、end、top

        带来的问题:内存被延迟释放

        解决办法:移动GAB中存活的对象到另一个GAB中,然后释放原GAB。

3 编译器和静态分析

3.1 编译器的结构

3.2 静态分析

        不执行程序代码,推导程序的行为,分析程序的性质。

        控制流:程序执行的流程

控制流图示例

        数据流:数据在控制流上的传递

3.3 过程内分析和过程间分析

        过程内分析:仅在函数内部进行分析

        过程间分析:考虑过程调用时参数传递和返回值的数据流和控制流

        过程间分析是个难点问题,因为需要同时分析控制流和数据流

4 Go编译器优化

4.1 函数内联

        将被调用函数的函数体的副本替换到调用位置上,同时重写代码以反映参数的绑定

优点:

  • 消除函数调用开销
  • 将过程间分析转化为过程内分析

缺点:

  • 函数体变大,icache不友好
  • 编译生成的Go镜像变大

4.2 Beast Mode

        调整函数内联的策略,使更多函数被内联,更多对象不逃逸,可以分配在栈上

4.3 逃逸分析

        分析代码中指针的动态作用域:指针在何处可以被访问

        若发现指针p在当前作用域s:

  • 作为参数传递给其他函数
  • 传递给全局变量
  • 传递给其他的goroutine
  • 传递给已逃逸的指针指向的对象

        则指针p指向的对象逃逸出s,反之则没有逃逸

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SwithunH

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值