Java Reference 详解

GC 回收策略-可达性分析

  • 从 GC Roots 开始向下搜索,搜索所走过的路径称为引用链,当一个对象到 GC Roots 没有任何引用链,则证明该对象是不可达的,将会被 GC 回收
  • 我们可以将指向某个对象的引用(Reference)置空来保证这个对象在下次 GC 运行的时候被回收
Object c = new Car();
c=null;
  • 但手动置空是一个很繁琐的事情,对于简单状况,手动置空是不需要程序员来做的,因为对于简单对象,当调用它的方法执行完毕之后,所指向它的引用会被 stack(栈)中 popup(出栈),当下次 GC 执行时就被回收了

什么是 Reference ?

  • Reference 是 Java 引用的顶层抽象类,它可以和普通的对象一样操作,在一定的限制条件下,还支持和 GC 进行交互

强引用

  • Java 引用中我们最熟悉的就是强引用,例如下面代码 object 和 str 都是强引用
Object object = new Object();
String str = "hello";
  • GC 在回收时会检测对象是否存在强引用,如果存在即使触发 GC 执行时也不会被回收
public void test(){
    Object object = new Object();
}
  • 当方法执行完毕之后,方法中申明的引用 object 就会被出栈,栈资源就会被释放,此时无任何引用指向 Object 对象,当下次触发 GC 时其就会被回收
  • 我们也可以显示的将引用赋值为 null,这样 GC 触发时就会回收该对象,例如 Vector 类中 clear 方法就是通过将引用赋值为 null 来实现清理工作的
   public synchronized E remove(int index) {
        modCount++;
        if (index >= elementCount)
            throw new ArrayIndexOutOfBoundsException(index);
        Object oldValue = elementData[index];

        int numMoved = elementCount - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                    numMoved);
        elementData[--elementCount] = null; // Let gc do its work

        return (E)oldValue;
    }

软引用

  • 它需要通过软引用对象来访问
SoftReference softRef = new SoftReference<>("aaaa");
  • 软引用对象在内存不足(OOM 异常),垃圾回收器会回收软引用所指向的对象,该特性适合用来实现缓存(如网页缓存,图片缓存)
  • 软引用可以和一个引用队列(ReferenceQueue)结合使用,如果软引用对象被 GC 回收,那么该软引用就会被加入到与之关联的引用队列中

弱引用

  • 它需要通过弱引用对象来访问
WeakReference weakRef = new WeakReference<>("aaaa");
  • 当一个对象仅仅被弱引用指向, 而没有任何其他强引用指向的时候, 如果 GC 运行, 那么这个对象就会被回收。它的一个特点就是不太确定何时被回收,由 GC 判断

虚引用

  • 虚引用和软、弱引用不同,它并不影响对象的生命周期,如果一个对象跟虚引用关联则跟没有引用与之关联一样,在任何时候都可能被 GC 回收
  • 虚引用必须和引用队列一起使用,当 GC 准备回收一个对象时,如果发现其有虚引用,则会把该虚引用加到与之关联的引用队列中
  • 一般用于实现追踪垃圾收集器的回收动作,比如在对象被回收时候,会调用对象的 finalize 方法,在使用虚引用可以实现该动作,也更安全
ReferenceQueue queue = new ReferenceQueue();
PhantomReference pr = new PhantomReference(new String("hello"), queue);

你可能感兴趣的:(Java Reference 详解)