单例对象无法被回收的真正原因要从java垃圾回收器开始说起
JAVA垃圾对象判断准则
Java中判断一个对象是否可以被回收是根据“可达性”来判定的。
可达性:
以一系列的称为 “GC Roots”的对象作为起始点,然后向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的,即可视为垃圾。
GC Roots点包含:
虚拟机栈(栈帧中的本地变量表)中引用的对象。
方法区中类静态属性引用的对象。
方法区中常量引用的对象。
本地方法栈中JNI(即一般说的Native方法)引用的对象。
垃圾回收算法
标记-清除算法
算法分为标记和清除两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象,它的标记过程就是使用可达性算法进行标记的。
主要缺点有两个:
效率问题,标记和清除两个过程的效率都不高
空间问题,标记清除之后会产生大量不连续的内存碎片
复制算法
算法将可用内存按照容量分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另一块上面,然后把已使用过的内存空间一次清理掉。
优点:
内存