一丶判断对象是否已经死亡
1.引用计数算法
实现简单,判定效率高。
难解决对象间相互循环引用的问题
2.可达性分析算法
- 通过一系列的可以成为“GC Roots”的对象作为起点,从这些节点向下搜索,搜索走过的路径称为引用链,当一个对象到Gc Roots没有任何引用链相连时,则证明对象是不可用的。
- 可以作为GC Roots的对象包括以下几种
- 虚拟机栈中引用的对象
- 方法区中类静态属性引用的对象
- 方法区中常量引用的对象
- 本地方法栈JNI,即native方法引用的对象
二丶垃圾收集算法
1.标记清除算法
- 标记出需要回收的对象,然后统一回收
- 缺点:标记清除两个过程效率都不高,产生的空间碎片太多
2.复制算法 - 将内存划分位大小相等的两块,每次只使用其中的一块。当其中一块内存用完了,就将依然存活的对象复制到另外一块上面去,然后再把已使用的内存空间清理掉。
- 实现简单,运行高效。代价是将内存缩小为了原来的一半。
- 现代商业虚拟机采用这种收集算法来回收新生代
- 将内存分为一块较大的Eden空间和两块较小的Survivor空间,每次使用Eden空间和其中一块Survior。当回收时,将Eden和Survior中还存活的对象一次性复制到另外一块Survior空间上,最后清理掉刚才用到的Survior空间和Eden空间。
- Eden和Survior空间大小比例为8:1
- 如果另外一块Survior空间没有足够空间存放上次新生代收集下来的存活的对象,这些对对象将直接通过分配担保机制进入老年代
3.标记整理算法
- 标记出需要回收的对象,然后将存活的对象都向一端移动,然后直接清理掉端边界以外的内存。
- 这种算法用来回收老年代
4.分代收集算法 - Java堆分为新生代与老年代
- 新生代每次垃圾收集都会有大量对象死去,少量存活,那就选用复制算法
- 老年代对象存活率高,没有额外的空间进行分配担保,使用标记清理或者标记整理算法来进行回收