任何提高效率或者节省开销的行为都可以称之为性能优化。
内存管理
为什么要进行内存管理:我们在开发过程中, 由于不是十分了解,从而造成的内存泄漏等问题,既会影响性能,也会触发一些奇怪的 bug 。
内存:由可读写单元组成,表示一片可操作空间。
管理:由人去操作一片空间的申请,使用,释放。
内存管理:开发者,申请。使用。释放空间。
垃圾回收
垃圾的定义:不可达对象和无不再被引用的对象。
不可达对象:从根上出发不可以被按照关系访问到(引用、作用连)的对象。这里根指全局变量。
内存管理是性能优化的原因,垃圾是被优化的对象,而处理垃圾的方案则被我们称为 GC 。
GC 算法
逻辑:查找和回收遵循的规则,找到内存中的垃圾,并释放回收空间。
GC 中的垃圾,不能访问的对象,不需要的对象。。
常用 GC 算法: 引用计数, 标记清除, 标记整理, 分代回收。
引用计数
机制:在对象内部添加一个引用数,判断引用数是否为 0 。当引用关系发生变化时,修改引用数,引用数为 0 时,立即回收。
优点:
1. 发现垃圾时,立即回收(时刻监控引用数)。
2. 最大限度减少程序暂停(可以立即回收垃圾)。
缺点:
1. 无法回收循环对象的引用。
2. 时间开销大(时刻监控引用数)。
标记清除
机制:先遍历所有对象并标记活动对象(即可达的对象),然后再次遍历所有对象,同时清除未标记的对象,去掉被标记对象的标记。最后进行空间回收。
优点:
1. 可以回收循环对象的引用。
缺点:
1. 空间碎片化,当一串地址存储了 A, B, C,三个变量,A,C 被清楚。那么剩下 A,C 释放出来的空间长度是固定的。而接下来被添加的变量长度是未知的。很难和 A,C 的长度完全相同,所以空间利用率一定会降低。
标记整理
机制:标记整理可一看作是标记清除的一个增强,同标记清除一样,先遍历所有对象,并标记所有活动对象。然后清除未标记的变量。只是在清除之前要移动将要被清除变量的位置,以便于释放出连续的空间。从而避免标记清除的缺点。
具体过程如下图 :


