对象状态判断
对象状态判断
引用计数算法
-
给对象添加一个引用极计数器,每引用一次+1,引用失效-1,当值为0时,表示对象不再被应引用;
-
但对于互相引用的对象无效;
可达性分析算法
通过一系列的称为“GC Roots”的对象作为起点,从这些起点开始向下搜索,所走过的路径称为“引用链”,当一个对象到GC Roots没有引用链时,表示对象不用;
可作为GC Roots的对象:
* 虚拟机栈(栈帧中的局部变量表)中引用的对象;
* 方法区中类静态属性引用的对象;
* 方法区中常量引用的对象
* 本地方法栈中JNI(即一般的Native方法)引用的对象;
再谈引用
对象除了“被引用”和“未被引用”两种状态外,还应该有第三种状态:缓存状态,即当内存空间足够时,保留在内存中,否则抛弃;因此引用可分为4中,分别是:
-
强引用
类似new操作的引用,只要存在,该对象不会被回收;
-
软引用
描述一些还有用但并非必需的对象。在系统要发生内存溢出异常之前,将会把这些对象列进回收范围之中进行第二次回收;如果还没有足够内存则抛出异常;
-
弱引用
强度比软引用更弱;
当发生垃圾回收时,会回收这些对象;
-
虚引用
最弱引用;一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得对象实例。该引用的唯一目的就是能在这个对象呗收集器回收时收到一个系统通知;
生存还是死亡
-
当通过可达性分析算法发现对象无引用链时,将进行第一次标记,此时还没有真正的回收;
-
标记之后进行一次筛选,条件是对象是否有必要执行finalize()方法,当该对象没有覆盖finalze(0方法或finalize()方法已经调用过时,称之为“没有必要执行”;
-
有必要执行时
将对象放置在一个叫做F-Queue的队列中,并在稍后由JVM自动创建的、低优先级的Finalizer线程去执行它,但不保证会等待它允许结束;原因是当对象的finalze()方法执行缓慢或异常时会导致F-Queue其他对象永久处于等待甚至整个内存回收系统崩溃;
稍后GC Root会对F-Queue中的对象进行第二次小规模的标记,如果没有重新引用;
-
将对象放入“即将回收”集合,等待回收;
回收方法区
方法区一般不要求实现垃圾回收,如果实现,主要回收两部分:
-
废弃常量
没有引用时,回收;常量池中的其他类(接口)、方法、字段的符号引用也类似;
-
无用的类
满足无用类的条件是
- 该类所有的实例都已经被回收,即Java堆中没有该类的实例;
- 加载该列的ClassLoader已经被回收;
- 该类对应的java.lang.Class读写没有在任何地方被引用,无法在任何地方通过放射访问该类的方法;
是否对类回收,JVM提供了参数进行配置;