这是我参与「第五届青训营」伴学笔记创作活动的第 5 天
本节课重点
主要学习了自动内存管理相关的知识
详细知识点
- 追踪垃圾回收
- 分代 GC (Generational GC)
- 引用计数
详细内容
自动内存管理
-
动态内存
- 程序在运行时估计需求动态分配的内存: malloc()
-
自动内存管理 (垃圾回收): 由程序语言的运行时系统自动动态内存
- 避免手动管理内存,专注于实现业务逻辑
- 保证了内存使用
正确性和安全性
-
三个任务
- 为新的对象分配空间
- 找到存活对象
- 回收死亡对象的内存空间
自动内存管理 可以自动回收无用的对象内存,让开发者专注业务逻辑,同时也在一定程度上提高了业务安全性。
追踪垃圾回收
-
对象被回收的条件: 指针指向关系不可达的对象
-
标记根对象
- 静态变量,全局变量,常量,线程栈等
-
标记: 找到的可达对象
- 求指针指向关系的传递闭包: 从根对象出发,找到所有可达对象
-
清理: 所有不可达对象
- 将存活对象复制到另外的内存空间 (copy GC)
- 将死亡对象的内存标记为可分配 (Mark-sweep GC)
- 移动并整理存活对象 (Mark-compact GC)
- 将存活对象复制到另外的内存空间 (copy GC)
-
根据对象的生命周期,受用不同的标记和清理策略
分代 GC (Generational GC)
分代假说: 大多数的对象年轻死亡
-
很多对象在分配出来后很快就不再使用了
-
每个对象都有年龄 (经历过的次数)
-
我们可以将内存分为两个部分
- 年轻代
- 常规对象分配
- 存活对象少,可以使用 copying GC
- GC 吞吐率高
- 老年代
- 对象趋向于一直活着,如果使用 copy GC 开销较大
- 采用 mark-sweep GC
- 年轻代
引用计数
- 每个对象都有一个与之关联的引用数目
- 对象存活的条件: 当且仅当引用数大于0时
- 优点
- 内存管理的操作被平坦到程序执行过程中
- 内存管理不需要了解runtime的实现细节:C++ 的 smart pointer
- 缺点
- 维护引用计数开销较大
- 无法回收环形数据结构
- 内存开销:每个对象都引入的额外内存空间存储引用数目
- 回收内存时依然可能引发暂停