一.自动内存管理
- 动态内存:
程序在运行时根据需求动态分配的内存
- 自动内存管理:
由程序语言的运行时系统管理动态内存
- 优点:
避免手动内存管理,专注于实现业务逻辑
保证内存使用的正确性和安全性
-
自动垃圾回收有三个任务需要关注:
- 为新对象分配内存
- 找到存活的对象
- 对于死亡的对象的内存空间的回收
-
为了完成这些任务,那么GC是最重要的关键点
- 好的gc的特点:
安全性:不能回收存活对象 **基本要求**
吞吐率:1-GC时间/程序运行总时间 **花在GC上的时间*
暂停时间:STW 业务是否感知
内存开销:GC元数据开销
- 目前GC有这些:
1. Serial GC:只有一个GC、
2. ParallelGC:支持多个collectors同时回收GC的算法、
3. Concurrent GC:mutator和collector可以**同时执行** ,**Collectors必须感知对象指向关系的改变**
- 垃圾回收算法:追踪垃圾回收、引用计数两种,其实还有其他的算法,这里介绍两种。其实和java的jvm差不多。
1. 追踪垃圾回收
- 对象被回收的条件:指针指向关系不可达的对象
- 标记根对象(静态变量、全局变量、常量、线程栈等)
- 标记:可达对象
- 求指针指向关系的传递闭包:从根对象出发,找到所有可达对象
- 清理:所有不可达对象
- 年轻代空间到老年代空间:将存活对象复制到另外的内存空间(Copying GC)
将死亡对象的内存标记为“可分配”(Mark-sweep GC)
移动并整理存活对象(Mark-compact GC)
2. 引用计数
- 每一个对象都有一个与之关联的引用数目
- 对象存活条件:当且仅当引用数大于0
- 优点:内存管理的操作被平摊到程序执行过程中
内存管理不需要了解runtime的实现细节:C++智能指针
- 缺点:维护引用计数的开销较大:通过原子操作保证对引用计数操作的原子性和可见性
无法回收环形数据结构
内存开销:每个对象都引入了额外的内存空间存储引用数目
回收内存时依然可能引发暂停