什么是垃圾?垃圾回收器是如何判断垃圾的?代码举例讲解

在Java中,垃圾代表无用的对象或空间,不能再被程序使用,只占用内存空间。垃圾回收器会对垃圾进行回收,释放其占用的内存空间。

垃圾回收器主要使用”可达性分析”算法来判断哪些对象是垃圾:

  1. 可达对象:被GC Roots对象直接或间接引用的对象。这些对象是存活的,不能回收。
  2. 不可达对象:不被GC Roots和其他可达对象引用的对象。这些对象是垃圾,可以回收。

GC Roots包括:

  1. 虚拟机栈中的对象:比如局部变量。
  2. 方法区中的类静态属性引用的对象。
  3. 方法区中常量引用的对象。
  4. 本地方法栈中Native方法引用的对象。

可达性分析算法的工作过程:

  1. 找出所有的GC Roots对象,这些对象是起始可达对象。
  2. 从GC Roots对象开始,通过引用关联找到所有可达对象。
  3. 可达对象还可以作为起始节点,继续通过引用找到更多可达对象。
  4. 重复步骤2和3,直到找出所有的可达对象。
  5. 不可达对象则归为垃圾,可以进行回收。

来看一个简单例子:

public class GarbageDemo {
    public static void main(String[] args) {
        Object a = new Object();
        Object b = new Object();
        Object c = new Object();

        a.b = b;  // a和b可达,c不可达

        b.c = c;  // a、b和c都可达

        a = null;  // a不可达,b和c可达

        c = null;  // b可达,a和c不可达  
    }
}

在该程序中:

  1. 一开始a、b和c都是可达对象,都不会被回收。
  2. a=null后,a变为不可达对象,成为垃圾。b和c还是可达的。
  3. c=null后,c变为不可达对象,也成为垃圾。b仍然是可达的,a是垃圾。