JVM垃圾回收算法

2018/06/12 Java
  • GC Roots对象用于可达性分析的起点对象,见下图示

在Java语言中,可作为GC Roots的对象包括以下四种:

  • 虚拟机栈(栈帧中的本地变量表)中引用的对象;
  • 方法区中类静态属性引用的对象;
  • 方法区中常量引用的对象;
  • 本地方法栈中JNI(即一般说的Native方法)引用的对象。

Java四种引用概念

  • 强引用:指在程序代码中普遍存在的,类似“Object obj = new Object();”这类的引用,只要强引用还存在,垃圾收集器永远不会回收掉被引用的对象;
  • 软引用:用来描述一些还有用但并非必需的对象。对于软引用关联的对象,在系统将要发生内存溢出异常前,将会把这些对象列进回收范围进行二次回收。如果这次回收还没有足够的内存,才会抛出内存溢出异常。JDK1.2之后提供了SoftReference类来实现软引用;
  • 弱引用:用来描述非必需的对象,但是它的强度比软引用更弱一些,被弱引用关联的对象只能生存到下一次垃圾收集发生之前。当垃圾收集器工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。在JDK1.2之后,提供了WeakReference类来实现弱引用;
  • 虚引用:最弱的一种引用关系。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。在JDK1.2之后,提供了PhantomReference类来实现虚引用。

对象的生存还是死亡

  • 对象宣告死亡至少要经历两次标记:1、可达性分析发现没有与GC Roots相连接的引用链,将被第一次标记并进行一次筛选,筛选的条件是是否有必要执行finalize()方法,如果虚拟机已经调用过该对象的finalize()方法或对象没有覆盖finalize()方法,则没有必要执行;
  • 筛选出的对象进入F-Queue队列,未筛选出的进入“即将回收”集合;
  • 虚拟机将自动建立一个低优先级的Finalizer线程去执行F-Queue队列里的对象finalize()方法,但这个执行不承诺会等待它运行结束。当对象在finalize()方法中重新与引用链上的任何一个对象建立关联(例如将this关键赋值给某个类变量或对象的成员变量),那么在第二次对F-Queue队列的对象标记过程中,它将被移出“即将回收”集合,逃脱死亡命运。

Search

    Table of Contents