自动内存管理 | 青训营

77 阅读4分钟

自动内存管理的相关介绍

为什么要了解并学习自动内存管理

性能优化,一直是研发者们所追求的。也正是因为性能的不断优化,我们在使用软件的过程中,页面的切换才能十分丝滑。而性能优化方面主要包括自动内存管理,go内存管理与优化,编译器和静态分析和go编译器优化。因此,了解并学习自动内存管理是十分有必要的。

自动内存管理的定义以及主要任务

自动内存管理定义:由程序语言的运行时系统回收动态内存,专注于实现业务逻辑。 主要目标:保证内存使用的正确性和安全性,为新对象分配空间,找到存活对象,回收死亡对象的内存空间。

主要概念解释

Mutator-----业务线程,分配新对象,修改对象指向关系 Collector---GC线程,找到存活对象,回收死亡对象的内存空间 对于GC线程,主要有三种:

  1. Serial GC----只有一个GC线程,并且在GC线程过程中,业务线程会暂停,等下GC线程结束
  2. Parallel GC----有多个GC线程,在GC线程和业务线程的处理方面,和Serial GC一样,也是将业务线程进行暂停。
  3. Concurrent GC----业务线程和GC线程可以同步进行,业务线程利用未使用GC线程的进行。需要注意的是,由于这里是同步进行,需要时刻感知对象指向关系的改变,避免错误。 评价或改良GC算法的方向: 安全性----不能够回收存活的对象 吞吐率----整个程序执行总时间中,非GC时间的所占百分比(吞吐率越小,管理效果越好) 暂停时间--当GC线程与业务线程不可同时进行时,GC线程所使用的时间,也就是业务线程暂停的时间。 内存开销--GC线程使用的元数据

追踪垃圾回收

对象被回收的条件:指针指向关系不可达的对象 标记根对象:静态变量,全局变量,常量,线程线等。(选择根对象,主要是选择整个程序都会存在的变量,或者变量的值是固定的) 标记:标记根对象所可达的对象(指针指向关系的传递闭包) 清理:不可达的对象 回收的方式:

  1. Copying GC:将已标记的对象复制到另外的内存空间
  2. Mark-sweep GC: 使用 free list 管理空闲内存 (将不可达的对象标记,以便需要使用空间的时候可以被再次使用) 个人的理解就是将不可达的对象当做未被占用的空间。
  3. Compact GC:原地整理对象 (将所有不可达的对象全部转移到存储空间的最前面)

分代GC

根据经历过GC的次数,划分为年轻代和老年代。针对于两种对象采用不同的策略。 年轻代---经历GC的次数少,说明很容易成为不可达的对象,因此采用Copying GC更方便,复制量少。 老年代---经历GC的次数多,一般都是可达的对象,因此采用Mark-sweep GC,既不用反复复制,也避免了对象在所在空间的多次移动。

引用计数

每个对象均有一个与之关联的引用数目,只有当对象的引用数大于0才可以存活。 优点: 内存管理的操作被平摊到程序执行过程中; 内存管理不需要了解runtime的实现细节。 缺点: 维护引用计数的开销较大--通过原子操作保证对引用计数操作的原子性和可见性; 无法回收环形数据结构(当所有的对象的引用数均为1,且构成了一个封闭的形状); 内存开销大---每个对象都需要存储引用数目; 回收内存时依然可能引发暂停。