自动内存管理 | 青训营笔记

74 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 8 天

性能优化可分为业务层优化和语言运行时优化。在前一篇关于性能优化的笔记中,更多提到的是业务层的性能优化,在了解语言运行时优化之前,本文将对自动内存管理的概念和常见方法进行简单介绍。

概念

自动内存管理,又称垃圾回收(garbage collection),是由程序语言的运行时系统管理动态内存,不仅能避免开发者手动管理内存,而且能保证内存使用的正确性和安全性。

自动内存管理有三个核心的任务:

  • 为新对象分配空间
  • 找到存活对象
  • 回收死亡对象的内存空间

完成任务以上任务可采用不同的GC算法,下面将简单介绍三种:

在介绍算法前先介绍两个下面用到的概念:

**Mutator:**业务线程,分配新对象,修改对象指向关系

**Collector:**GC线程,找到存活对象,回收死亡对象的内存空间

  • Serial GC

只有一个Collector。当需要进行GC操作时,先暂停所有Mutator,再用一个Collector去进行内存的标记和回收,最后当GC操作结束后就恢复所有Mutator的执行。

  • Parallel GC

支持多个Collector同时回收。当需要进行GC操作时,先暂停所有Mutator,再用多个Collector去同步进行内存的标记和回收,最后当GC操作结束后就恢复所有Mutator的执行。

  • Concurrent GC

mutator(s)和collector(s)可以**同时执行。**当需要进行GC操作时,可以一边collector进行内存的标记和回收,一边mutator继续执行,最后当GC操作结束后就休眠collector,mutator能够继续同步执行。相较前两种GC,这里的Collectors必须要能够感知对象指向关系的改变。

常见方法

追踪垃圾回收

回收条件:指针指向关系不可达的对象

回收步骤:

  1. 标记根对象,例如静态变量、全局变量、常量、线程栈等
  2. 从根对象出发,找到所有可达对象
  3. 清理所有不可达的对象,不同情形下清理策略可能不同,下面将简单介绍三种清理策略:
  • Copying GC:将对象复制到另外的内存空间
  • Mark-sweep GC:使用free list 管理空闲内存
  • Mark-compact GC:原地整理对象

清理策略的选择是依据对象的生命周期进行的

引用计数

每个对象都有一个与之关联的引用数目。

回收条件:引用数=0

优点:

  • 内存管理操作被平摊到程序执行过程中
  • 内存管理不需要了解runtime的实现细节

缺点:

  • 维护引用计数的开销较大
  • 无法回收环形数据结构
  • 需额外空间计数,增大内存开销
  • 回收内存时依然可能引发暂停

总结

垃圾回收对于开发者来说是自动化且不可见的,但这并不表明我们不需要关注它。通过学习发现,垃圾回收的过程其实并不简单也有许多算法。所有对于开发者来说,我们也需要关注内存管理,了解其原理后选择适合的自动内存管理方式也是很有必要的。