这篇文章主要用于最近在读的垃圾回收算法与实现这本书中的各种方法的总结,边读边进行记录。方便之后会看的时候可以直接进行查阅。
基本概念名词
头 保存对象本身信息,包含对象的大小和对象的种类,每种算法的实现中头包含的内容也不相同
域 对象使用者在对象中可访问的部分为域。
mutator mutator就是程序本身
活动/非活动对象 能通过mutator引用访问到的对象为活动对象,反之为非活动对象。
根root 直接或间接从全局变量空间引用的对象为活动对象。能作为根的对象,
- 全局static变量
- 栈中变量(代码中方法的局部变量)
- 寄存器
- 常量
- 本地方法栈中引用的对象
- 已经启动并且未停止的线程
评价标准 吞吐量,最大暂停时间,堆使用效率,访问局部性
GC-标记-清除算法
标记阶段把所有活动对象做上标记,清除阶段把没有标记的对象回收。
标记阶段:遍历对象并标记。使用深度优先搜索比广度优先搜索使用更少的内存。
清除阶段:遍历堆内存,根据标记位进行对象内存的清除,把垃圾对象所占用的内存地址链接到空闲连链表
分配过程:进行新的对象创建的时候,搜索空闲链表找到空闲的内存地址空间。
优先
- 实现简单
- 与保守式算法兼容,GC标记清除算法不会移动对象,
缺点
- 碎片化
- 分配速度,所有操作都需要遍历空闲链表和堆空间。
- 与写时复制技术不兼容,写时复制属于延时操作,GC回收时不应该直接操作内存空间。
优化方法
BiBOP 利用类似字典哈希的方法对内存中的分块进行管理,不同大小分块对应不同的链表,在分配的时候可以有效提升分配效率,避免了遍历整个空闲链表
位图标记 使用bitmap将所有的堆内存地址空间进行映射,有效解决了缺点第三条的写时复制相冲突,可以作伪删除操作
引用计数
引用计数的方法是在所有的Object属性中增加一个计数器头。当对象被引用之后,计数器+1, 反之计数器-1。当计数器的值为0的时候,GC程序判断此对象为垃圾对象,将其加入到空闲链表当中发现时立即进行回收。对象自身会对自己进行判断。
优点
- 可立即进行垃圾回收,GC程序的运行和内存管理同时进行,可以提高分配时的成功率。
- 最大暂停时间短,GC程序的回收工作只发生在发现垃圾的时候。减少GC的运行时间。
- 没有必要沿指针查找
缺点
- 计数器增减操作频繁
- 计数器占位空间
- 无法处理循环引用
部分标记-清除算法
部分标记清除算法目的是为了解决引用计数方法中存在的无法回收循环引用对象的问题。GC进行标记清除是遍历所有对象,产生无用的搜索。
“部分标记 - 清除算法”(Partial Mark & Sweep)查找非活动对象。 所有对象将标记不同颜色
- 黑:绝对不是垃圾的对象(对象产生式的初始颜色)
- 白:绝对是垃圾的对象
- 灰:所有过的对象