这是我参与「第三届青训营 -后端场」笔记创作活动的第5篇笔记
垃圾标记算法
1.引用计数
- 对每个变量都维护一个引用计数,每当该变量被其他变量引用时,引用数加一;当引用数减为0时,销毁该变量,被该变量引用的其他变量引用数减一。
优点:
- 内存管理的操作被平摊到程序运行中:指针传递的过程中进行引用计数的增减
- 不需要了解 runtime 的细节:因为不需要标记 GC roots,因此不需要知道哪里是全局变量、线程栈等 缺点:
- 开销大,因为对象可能会被多线程访问,对引用计数的修改需要原子操作保证原子性和可见性
- 无法回收环形数据结构(致命缺陷)
- 每个对象都引入额外存储空间存储引用计数
- 虽然引用计数的操作被平摊到程序运行过程中,但是回收大的数据结构依然可能引发暂停
2.可达性分析算法
- 被回收的条件:不可达对象
- 过程
- 标记根对象 (GC roots): 静态变量、全局变量、常量、线程栈等
- 标记:找到所有可达对象
- 清理:回收所有不可达对象占据的内存空间
垃圾回收算法
1.标记清除
首先标记出所有死亡的对象,然后把所有死亡的的对象进行清除操作。这里所谓的清除并不是真的置空,而是把需要清除的对象地址保存在空闲的地址列表里。下次有新对象需要加载时,判断垃圾的位置空间是否够,如果够就存放
缺点:
- 效率不高
- 在进行GC的时候,需要停止整个应用程序,导致用户体验差
- 这种方式清理出来的空闲内存是不连续的,产生内存碎片。需要维护一个空闲列表
2.标记整理
把所有的存活对象移动到一起,然后清空存活边界以外的所有对象。
优点:
- 不会产生空间碎片
缺点:
- 需要移动对象,造成更高的开销。
因此该算法适合用于新生代变量的清理(存活对象少)