Go语言内存管理 | 青训营笔记

79 阅读2分钟
这是我参与「第五届青训营」伴学笔记创作活动的第 4 天

自动内存管理

概念

GC算法的评价方法

安全性是指不能回收存活的对象。

吞吐率计算方法 1-GC时间/程序执行时间。

暂停时间决定了业务是否感知。

内存开销是GC元数据的开销。

追踪垃圾回收

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

标记根对象:静态变量、全局变量、常量、线程栈等。

标记后清理不可达对象。

分代GC

回收依据

分代假说。

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

每个对象的年龄:经历GC的次数。

对年轻和年老的对象有不同的GC策略。

策略

对年轻代的对象,使用常规的对象分配由于存活对象少,可以采用copying collection。GC吞吐率高。

对老年代的对象,反复复制开销大,可以采用mark-sweep collection。

引用计数

每个对象都有一个与之关联的引用数目。

存活条件是引用数大于0。

Go内存管理及优化

内存分配

分块,目的是为对象在堆上分配内存。

提前将内存分块,向系统申请大块内存,将内存分块,再分成特定大小的小块。

根据对象的大小,选择最合适的块并返回。

内存管理优化

使用pprof工具查看对象分配情况。

Balanced GC

GAB对Go 内存管理来说是一个大对象,本质是多个小对象的分配合并成一次大对象的分配。

编译器和静态分析

编译器结构

是重要的系统软件。

分析部分:词法分析,生成词索;语法分析,生成语法树;语义分析,收集类型信息,进行语义检查;中间代码生成。

综合部分:代码优化,机器无关优化,生成优化后的IR;生成目标代码。

静态分析

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

过程内分析和过程间分析

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

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

Go编译器优化

函数内联

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

优点:消除函数调用开销,将过程间分析转化为过程内分析。

缺点:函数体变大,icache不友好,编译生成的Go 镜像变大。

逃逸分析

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

优化:未逃逸的对象可以在栈上分配,减少在堆的分配,降低GC负担。