java强引用、软引用、弱引用、虚引用

一、概述

从JDK1.2开始,就提供了四种类型的引用:强引用、软引用、弱引用和虚引用。

Java中提供这四种引用类型主要有两个目的:第一是可以让程序员通过代码的方式决定某些对象的生命周期;第二是有利于JVM进行垃圾回收。
在这里插入图片描述

二、强引用

Object object = new Object(); 就是一个强引用,只有当gcroot不可达时,gc才会回收

三、软引用

软引用是用来描述一些有用但并不是必需的对象,在Java中用java.lang.ref.SoftReference类来表示。对于软引用关联着的对象,只有在内存不足的时候JVM才会回收该对象。

package org.fool.reference;  
  
import java.lang.ref.SoftReference;  
  
public class SoftRefereneceTest {  
    public static void main(String[] args) {  
        /** 
         * 软引用是用来描述一些有用但并不是必需的对象,在Java中用java.lang.ref.SoftReference类来表示。 
         * 对于软引用关联着的对象,只有在内存不足的时候JVM才会回收该对象。因此,这一点可以很好地用来解决OOM的问题, 
         * 并且这个特性很适合用来实现缓存:比如网页缓存、图片缓存等。 
         * 软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被JVM回收,这个软引用就会被加入到与之关联的引用队列中。 
         */  
        SoftReference<String> sr = new SoftReference<>(new String("hello"));  
          
        System.out.println(sr.get());   // hello  
          
        System.gc();  
          
        System.out.println(sr.get());   // hello  
    }  
}

四、弱引用

弱引用也是用来描述非必需对象的,当JVM进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象。在java中,用java.lang.ref.WeakReference类来表示。
jdk动态代理生成的类对象就是以弱引用为key的map,所以gc时这些对象会被回收,重新使用时会重新生成,这样避免了程序运行时如果积累了大量的代理类对象可被回收,不会因为代理类而发生oom

package org.fool.reference;  
  
import java.lang.ref.WeakReference;  
  
public class WeakReferenceTest {  
    public static void main(String[] args) {  
        /** 
         * 弱引用也是用来描述非必需对象的,当JVM进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象。 
         * 在java中,用java.lang.ref.WeakReference类来表示。 
         */  
        WeakReference<String> wr = new WeakReference<>(new String("hello"));  
          
        System.out.println(wr.get());   // hello  
          
        System.gc();  
          
        System.out.println(wr.get());   // null  
        /** 
         * 第二个输出结果是null,这说明只要JVM进行垃圾回收,被弱引用关联的对象必定会被回收掉。 
         * 不过要注意的是,这里所说的被弱引用关联的对象是指只有弱引用与之关联, 
         * 如果存在强引用同时与之关联,则进行垃圾回收时也不会回收该对象(软引用也是如此)。 
         * 弱引用可以和一个引用队列(ReferenceQueue)联合使用, 
         * 如果弱引用所引用的对象被JVM回收,这个软引用就会被加入到与之关联的引用队列中。 
         */  
    }  
}

五、虚引用

虚引用和前面的软引用、弱引用不同,它并不影响对象的生命周期。在java中用java.lang.ref.PhantomReference类表示。如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收。

package org.fool.reference;  
  
import java.lang.ref.PhantomReference;  
import java.lang.ref.ReferenceQueue;  
  
public class PhantomReferenceTest {  
    public static void main(String[] args) {  
        /** 
         * 虚引用和前面的软引用、弱引用不同,它并不影响对象的生命周期。在java中用java.lang.ref.PhantomReference类表示。 
         * 如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收。 
         * 要注意的是,虚引用必须和引用队列关联使用,当垃圾回收器准备回收一个对象时, 
         * 如果发现它还有虚引用,就会把这个虚引用加入到与之 关联的引用队列中。 
         * 程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。 
         * 如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。 
         */  
          
        ReferenceQueue<String> queue = new ReferenceQueue<>();  
  
        PhantomReference<String> pr = new PhantomReference<>(new String("hello"), queue);  
      
        System.out.println(pr.get());   // null  
          
        System.gc();  
          
        System.out.println(pr.get());   // null  
    }  
}
发布了52 篇原创文章 · 获赞 7 · 访问量 3793

猜你喜欢

转载自blog.csdn.net/maomaoqiukqq/article/details/103940921