这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天,本文主要以概括总结,全局记录为主,而不是作为细致的知识点讲解,细节之处多有疏忽还望多多包容。
一、本堂课重点内容:
- 自动内存管理
- Go内存管理及优化
二、详细知识点介绍:
内存管理
相关概念
- Mutator: 业务线程,用于分配新对象,也能修改对象指向关系
- Collector:GC 线程,用于回收死亡对象的内存空间,它可以标记存活对象,并且必须感知对象指向关系的改变
- Serial GC:只有一个 collector
- Parallel GC:支持多个 collectors 同时回收的 GC 算法
- Concurrent GC:支持 M 和 C 同时执行,多线程
如何评价 GC 算法
- 安全性
- 吞吐率(1- GC 时间 / 程序执行总时间)
- 暂停时间
- 内存开销
追踪垃圾回收
-
标记根对象: 根对象有 静态变量,全局变量,常量,线程栈等
-
标记所有可达对象: 求指针指向关系的 传递闭包,也就是从根对象出发,找到所有的可达对象
-
清理所有的不可达对象:
- 将存活对象复制到另外的内存空间(Copy GC,原先的内存可直接分配)
- 将死亡对象的内存标记为“可分配”(Mark - sweep GC,使用 free list 管理可分配的空间)
- 移动并整理存活的对象(Mark - Compact GC)
分代 GC
- 年轻代
- 常规的对象分配
- 由于存活对象很少,可以采用 Copy GC
- GC 吞吐率很高
- 老年代
- 对象趋于一直活着,反复复制开销较大
- 可以采用 mark - sweep GC
引用计数
-
每个对象都有一个与自己关联的引用数目,类似论文引用次数
-
当且仅当引用数大于 0 ,对象存活
三、实践练习例子:
无代码实践
四、课后个人总结:
- Go 的 GC 和 Java 的大差不差,学起来也是轻车熟路