java堆中存放着几乎所有的对象实例,所以java堆也就是垃圾回收的主要区域,要想学习垃圾回收算法,首先要明白堆的区域分配
垃圾回收算法结构
引用计数法 |
引用计数法如何判断对象是否存活?给对象添加一个引用计数器,每当有一个地方引用它时,计数器的值就加一;引用失效则减一;任何时刻计数器为0的对象是不能再使用的,简单说就是看有没有人引用它。
优点:实现简单,判定效率较高
缺点:无法解决对象的循环引用问题,这一缺点也就造成了主流Java虚拟机基本上没有使用该算法的。
可达性分析算法 |
示意图
从GC Roots出发,可以看出object5 object6 object7到GC Roots没有任何引用链
基本思想:通过一系列称作“GC Roots”的对象作为起始点,从节点开始向下搜索,搜索走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连时,证明此对象是不可用的。
标记清除 |
就像它的名字一样,标记清除算法就是将需要回收的算法标记上,然后统一回收
缺点:效率不高,容易产生内存碎片
复制算法 |
它可将内存按照容量分为大小相等的两块,每次只使用其中的一块,当这一块的内存用完了,就将还存活着的对象复制到另一块上面,然后将已经使用过的内存空间一次性清理掉
优点:内存分配无需考虑内存碎片的问题;实现简单运行高效
缺点:讲内存缩小为一半
标记压缩 |
标记过程和标记清除算法一致,后续则让所有存活的对象向一侧移动,实现压缩,可以直接清理掉端边界以外的内存
分代收集算法 |
当前的商业虚拟机都使用分代收集算法,根据内存中对象的生存周期分为新生代和老年代,对应分配不同的算法,新生代采用复制算法,而老年代采用标记-清除和标记-压缩算法
谈谈引用 |
强引用
普遍存在的如下引用
Object obj=new Object();
只要强引用还在,被引用对象就不会被回收
软引用
用来描述有用但非必须的对象
弱引用
非必需对象
虚引用
最弱的引用关系