判断对象是否存活的方法
引用计数
对象有一个属性引用次数,当对象被引用时,该属性值加一。当对象取消引用时减一。引用次数为0时,表明该对象不会再被使用,认为是死亡对象。
可达性分析
从GC Roots开始往下搜索对象,搜索的路径构成引用链。若一个对象无引用链与GC Roots相连为不可达,否则可达。
GC Roots:
- 虚拟机栈中引用的对象
- 方法区静态属性引用的对象
- 方法区常量引用的对象
- 本地方法栈中JNI引用的对象
垃圾收集算法
标记-清除(Mark Sweep)算法
每个对象对应一个标记位,记录是否可达。
- 标记。对空间中对象进行可达性分析,标记可达对象。
- 清除不可达对象。
优点:
- 只需找到对象被一个GC Roots可达的对象引用即可判断可达。
- 不移动对象
缺点: - 内存碎片问题。当执行多次标记清除算法后,会产生大量小的内存碎片。当要创建大对象,会遇到无足够连续空间分配。
- 标记和清除两个过程的效率都不高。标记要递归和遍历整个空间一遍,清除也要遍历整个空间一遍。
标记-压缩(Mark Compact)算法
- 标记。对空间中对象进行可达性分析,标记可达对象。
- 压缩。将可达对象全部移向空间的一端,清除可达对象边界之外的内存空间。
优点:
- 无内存碎片问题。
- 压缩过程,移动对象的效率不高。
缺点: - 当存活的对象多时,复制次数变多,效率变低。
复制(Copy)算法
将内存空间分为两半A0、A1。
- 对空间A0进行可达性分析,标记可达对象。
- 将可达对象复制到空间A1, 清除A0空间。
优点:
- 无内存碎片问题。
- 实现简单
缺点: - 内存空间仅一半可利用,空间利用率不高
|