判断对象是否存活主流有两种方式:
1.引用计数算法
给每个对象添加一个引用计数器,每当有一个地方引用它时,计数器的值就加1;当引用失效时,计数器的值就减1。任何时刻计数器的值为0时就说明此对象是不可以再被使用的。
这种方式实现简单,判断效率高。但是存在问题,当两个对象互相引用时,而且这两个对象再无任何引用,会导致这两个对象的引用计数器均不为0,但是这两个对象应该是要被回收的。java虚拟机确实没有采用这种判断方法。
2.可达性分析算法
通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路劲称为引用链,当一个对象到GC Roots没有任何引用链相连也就是不可达时,证明此对象不可用。
java中能作为“GC Roots”的对象包括以下几种:
1.虚拟机栈(栈帧中的本地变量表)中引用的对象
2.方法区中类静态属性引用的对象
3.方法区中常量引用的对象
4.本地方法栈中JNI(即一般说的Native方法)引用的对象
下面补充说下java引用的分类:
引用分为强引用、软引用、弱引用、虚引用,强度依次降低,下面分别说下它们的特点
强引用:在程序代码中普遍存在的,类似“Object obj = new Object()”,只要强引用还存在,垃圾收集器永远不会回收掉被引用的对象
弱引用:弱引用也是用来描述非必须对象,但是强度比软引用更弱,被其关联的对象只能生存到下一次垃圾收集发生之前,也就是说,如果发生垃圾收集行为,无论当前内存是否足够,都会回收掉这些对象。
虚引用:也被称为幽灵引用或者幻影引用。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。设置虚引用的唯一目的就是能在这个对象被收集器回收时收到一个系统通知