这是我参与「第五届青训营 」伴学笔记创作活动的第 4 天
笔记概述:
- 自动内存管理背景和意义
- 概念和评价方法
- 追踪垃圾回收
- 引用计数
- 分代GC
背景和意义
优化是任何工程中不可缺少的一部分,提高软件系统处理能力,充分发掘计算机算力,可以提升用户体验, 降低成本提高效率。
由于庞大的数据量,机器量,很小的优化对于工程来说也有着巨大的意义。
优化层面
- 业务代码
- SDK(软件开发工具包)
- 基础库
- 语言进行时
- OS
!!依赖数据去评估性能问题,而不是靠主观的臆断!!
性能优化应该注意的
- 在保证结构稳定的情况下改进具体实现
- 覆盖尽量多的场景测试用例
- 给用户的文档:做了什么,没做什么,效果
- 隔离性:通过选项控制是否开启优化
- 可观测:必要的日志输出
以下介绍了内存管理优化中的自动内存回收,也称垃圾回收**
自动内存管理(垃圾回收)
避免手动内存管理,专注于业务实现逻辑
- 为新对象分配空间
- 找到存活对象
- 回收死亡对象的内存空间
mutator: 业务线程,分配新对象,修改对象指向
collector: GC 线程,找到存活对象,回收死亡对象的内存空间(必须感知对象指向关系的改变
serialGC: 只有一个collector
Paraller GC: 支持多个collectors同时回收的GC算法
concurrent GC: mutator(s) and collector(s) 业务与回收同时进行
GC的评价内容:
- 安全性:不能回收存活对象
- 吞吐率:1-GC时间/总时间
- 暂停时间:stop the world(业务是否感知
- 内存开销:GC的内存开销
Tracing garbage collection追踪垃圾回收
步骤:
- 标记根对象:静态变量、全局变量、常量、线程栈等
- 标记:找到所有可达对象 求标记第一部分对象指针所指向的对象传递闭包
- 清理所有不可达对象
清理策略:
- Copying GC:将可达对象复制到另外的内存空间,删除原空间
- Mark—sweep GC:使用free list管理空闲内存(死亡对象部分内存),使用时跳过存活对象
- Mark-compact GC:无额外空间,原地将可达对象压缩到内存空间开头,清理出后方内存
分代GC
假设很多对象用完之后回收了
年龄:经历过GC的次数
根据年轻与年老分不同的GC策略,降低整体内存管理的开销
- 年轻代 常规的对象分配 由于存活对象较少,采用copying GC
- 老年代 趋向于一直活着 可以采用mark-sweep collection
引用计数
每个对象都有一个与之关联的引用计数
存活条件:引用记数大于0
- 优点:
内存管理平摊到程序的执行中
不需要了解runtime的实现细节,如c++智能指针
- 缺点:
维护引用计数开销较大:原子操作保证计数操作的原子性和可见性
无法回收环形数据结构,解决:weak reference
内存开销:每个对象都引入额外内存空间来存储引用计数
回收大的内存时依然可能引发暂停
总结内容
笔记概述:
- 自动内存管理背景和意义
- 概念和评价方法
- 追踪垃圾回收
- 引用计数
- 分代GC
讲师推荐的读物:《THE GARBAGE COLLETCION HANDBOOK》有中文版,推荐英文版