一、判断对象是否已经死亡的方法
(1)引用计数法
基本思路:在一个对象中添加一个引用计数器,每当有一个地方引用他时,计数器的值就加一;当引用失效时,计数器减一;任何时刻计数器为零的对象是不可能再被使用的(对象已死亡)。
弊端:需要配合大量额外处理才能保证正确的工作,例如:对象之间的循环引用
(2)可达性分析算法
基本思路:通过一系列称为 “GC Roots” 的跟对象为起始节点集,从这些结点开始,根据引用关系乡下搜索,搜索过程所走过的路径称为 “引用链” ,如果某个对象到 GC Roots 间没有任何引用链相连,或者用图论的话来说就是从 GC Roots 到这个对象不可达时,则证明这个对象是不可能在被使用的(对象与已死亡)。
固定可以作为 GC Roots 的对象:
1 . 在虚拟机栈中引用的对象;例如:各个线程被调用的方法堆栈中使用到的参数,局部变量,零食变量。
2 . 在方法区中类静态属性引用的对象;例如:Java类的引用类型静态变量。
3 . 在方法区中常量引用的对象;例如:字符串常量池中的引用。
4 . 在本地方法中JNI( Native 方法)引用的对象。
5 . Java虚拟机内部的引用;例如: 基本类型对应的Class对象,常驻的异常对象,系统类加载器。
6 . 被同步锁( synchronized关键字)持有的对象;
7 . 反映Java虚拟机内部情况的JMXBean,JVMTI中注册的回调,本地代码缓存。
(3)引用
不论是引用计数法还是可达性分析算法,判断对象的存活都和 ”引用“ 离不开关系。 引用分为:强引用,软引用,弱引用,虚引用。引用强度依次逐渐减弱。
强引用:最传统引用的含义,是指代码中普遍存在的引用赋值,只要强引用关系存在,垃圾回收器就不会回收被引用的对象;
软引用:用来描述一些还有用,但非必须的对象。只要被软引用关联的对象,在系统将要溢出前,会把这些对象列入回收范围之中进行第二次回收,如果这次回收还没有足够的内存,才会抛出异常。由SoftReference类来实现软引用。
弱引用:用来描述那些非必须对象,被弱引用关联的对象只能生存到下一次垃圾收集发生为止。当垃圾回收工作开始时,无论内存是否足够,都会回收该对象。
虚引用:也称为 “幽灵引用” 或者 “幻影引用” 。一个对象是否有虚引用存在,完全不会对其生存时间有影响,也无法通过它来获取一个对象的实例,设置虚引用的目的只是为了在这个对象被垃圾回收器回收是系统收到一个信息。