JVM中判断对象存活与死亡
1 引用计数法
每个对象会分配一个引用计数器, 当对象被引用时, 计数器加1, 当引用失效时, 计数器减1, 当计数器为0时, 代表该对象已经没用啦。
1.1 优点
实现简单, 判定效率高
1.2 缺点
很难解决对象之间相互循环引用的情况
2 可达性分析算法
以GC ROOT为起点, 从这写节点开始搜索, 搜索所走过的路径称之为引用链, 当一个对象到GC ROOT没有任何引用连接时, 就代表该可对象已经没用啦。
2.1 可以作为GC ROOT的对象
虚拟机栈(栈帧中的本地变量表)中引用的对象、方法区中类静态属性引用的对象、 方法区中常量引用的对象、 本地方法栈中JNI(即一般说的Native)引用的对象。
3 Java中的引用类型
3.1 强引用 (Strong Reference)
强引用指程序代码中普遍存在的, 如: Object obj = new Object();只要强引用还存在, 垃圾收集器就永远不会回收它。
3.2 软引用 (Soft Reference)
软引用是用来描述一些还有用但非必需的对象。 软引用的对象在将要发生内存溢出异常之前,会被列进回收范围之中进行第二次回收, 如果这次回收还没有足够的内存,才会抛出内存溢出异常。
3.3 弱引用 (Weak Reference)
弱引用是用来描述非必需的对象。当垃圾收集器工作时, 无论当前内存是否足够, 都会回收掉被弱引用关联的对象。
3.4 虚引用 (Phantom Reference)
虚引用也称幻影引用或幽灵引用, 它是最弱的一种引用关系。 一个对象是否有虚引用存在,不会对其生存时间构成影响,也无法通过一个虚引用获取一个对象实例。为一个对象关联虚引用的主要目的是为了能在这个对象被垃圾回收器回收时收到一个系统通知。
4 可达性分析算法中不可达的对象一定会被回收吗?
不一定。 当对象到GC ROOT不可达时, 虚拟机会判断该对象是否有必要执行finalize()方法。当对象没有覆盖finalize()方法或已经执行过finalize()方法,那该对象将会被回收, 反之有必要执行finalize()方法,会将该对象放入一个叫做F—Queue的队列中 , 由虚拟机创建低优先级线程去执行它,在执行finalize()方法过程中可以让该对象继续存活, 但虚拟机不保证等待方法执行结束,万一finalize()方法执行慢亦或是死循环呢?