这是我参与「第五届青训营 」笔记创作活动的第4天
前言
本系列文章创作基于作者的浅薄知识和其他大佬的深刻见解,主要记录青训营学习过程中我对一些东西的个人理解,也用于参加「第五届青训营」的笔记创作活动,请多指教。
自动内存管理
在我前面三个学期的学习中,对于语言的学习个人感觉总是囫囵吞枣、不求甚解的,简单来说就是没有深入语言的底层机制和逻辑,仅仅是学习语法学习应用;加之我思维比较懒惰有时不愿深究,这样的学习给我带来了一种莫名的空虚感。于是,今天要迈出深挖的第一步。
-
动态内存
- 程序在运行时根据需求动态分配的内存:malloc() ———— 需要时分配,不需要时回收。
-
自动内存管理(垃圾回收):由程序语言的运行时系统管理动态内存
- 避免手动内存管理,专注于实现业务逻辑
- 保证内存使用的正确性和安全性:double-free problem, use-after-free problem
-
三个任务
- 为新对象分配空间
- 找到存活对象
- 回收死亡对象的内存空间
相关概念
-
Mutator: 业务线程,分配新对象,修改对象指向关系
-
Collector: GC 线程,找到存活对象,回收死亡对象的内存空间
-
Serial GC: 只有一个 collector
-
Parallel GC: 支持多个 collectors 同时回收的 GC 算法
-
Concurrent GC: mutator(s) 和 collector(s) 可以同时执行
评价GC算法的几个标准
-
安全性(Safety):指垃圾回收器不应回收存活的对象;
-
吞吐率(Throughput):指垃圾回收器花在 GC 上的时间占程序执行总时间的比率;
-
暂停时间(Pause time):指垃圾回收导致业务线程挂起(暂停)的时间(GC 导致的暂停被称为 stop the world, STW)
-
内存开销(Space overhead):指垃圾回收器元数据占用的内存开销;
>> 追踪垃圾回收(Tracing garbage collection)
-
对象被回收的条件: 指针指向关系不可达的对象
-
标记根对象
- 静态变量、全局变量、常量、线程栈等
-
标记:找到可达对象
- 求指针指向关系的传递闭包: 从根对象出发,找到所有可达对象
-
清理: 所有不可达对象
- 将存活对象复制到另外的内存空间(Copying GC)
- 将死亡对象的内存标记为“可分配“(Mark-sweep GC)
- 移动并整理存活对象(Mark-compact GC)
-
根据对象的生命周期,使用不同的标记和清理策略
-
Copying GC: 将对象复制到另外的内存空间
-
Mark-sweep GC: 使用 free list 管理空闲内存
-
Compact GC: 原地整理对象
>> 分代GC (Generational GC)
>> 引用计数 (Reference counting)
-
引用
本文图片和部分文字来自以下链接:
高性能 Go 语言发行版优化与落地实践 .pptx - 飞书云文档 (feishu.cn)