引用大佬的博客: Java:强引用,软引用,弱引用和虚引用

建议直接看大佬的博客,我这里只做总结。

总结

强引用 相当于 Object obj=new Object()这种引用就是强引用,即使OOM也不会被垃圾回收器进行回收
软引用 如果将要发生了OOM(内存不够用了)则会将对象自动回收
弱引用 只要发生了gc()就会进行回收虚引用的对象
虚引用 主要用来跟踪对象被垃圾回收的活动。虚引用必须和引用队列关联使用。

案例:

import java.lang.ref.*;

public class WeakReferenceDemo {

    public static void main(String[] args) {
        softReferenceTest();// 软引用
        weakReferenceTest();// 弱引用
    }

    /**
     * 软引用测试案例
     * 会发现gc后软引用还能获取"hello world!!!",只有将要OOM的gc才会回收对象那么返回null
     */
    private static void softReferenceTest() {
        String helloWorldString = new String("hello world!!!"); // 在堆中根据常量字符串创建一个新的字符串对象
        SoftReference<String> stringSoftReference = new SoftReference<>(helloWorldString);
        System.out.println("打印一下软引用的字符串:" + stringSoftReference.get());//没有进行gc前软引用能得到对象
        /**
         * 置 null 的作用
         * 去除helloWorldString强引用字符串"hello world!!!",
         * 因为对象一旦被强引用指向,即使内存不够,宁愿报错也不会被回收改对象,相当于"hello world!!!"原先由两个引用指向这个对象
         */
        helloWorldString = null;
        System.gc();//进行垃圾回收
        stringSoftReference.get();
        System.out.println("软引用的字符串被垃圾回收了,得到的字符串是:" + stringSoftReference.get());
    }

    /**
     * 弱引用测试案例
     * 会发现gc后,弱引用不能获取"hello world!!!"
     */
    private static void weakReferenceTest() {
        String helloWorldString = new String("hello world!!!"); // 在堆中根据常量字符串创建一个新的字符串对象
        WeakReference<String> stringWeakReference = new WeakReference<>(helloWorldString);// 创建一个弱引用,将弱引用指向堆中的那个字符串

        /**
         * 置 null 的作用
         * 去除helloWorldString强引用字符串"hello world!!!",
         * 因为对象一旦被强引用指向,即使内存不够,宁愿报错也不会被回收改对象,相当于"hello world!!!"原先由两个引用指向这个对象
         */
        helloWorldString = null;
        System.out.println("打印一下弱引用的字符串:" + stringWeakReference.get());//没有进行gc前软引用能得到对象
        System.gc();//进行垃圾回收
        stringWeakReference.get();
        System.out.println("弱引用的字符串被垃圾回收了,得到的字符串是:" + stringWeakReference.get());
    }
}

再度总结

之所以要分成这四种引用,就是在gc的时候被引用的对象是否会被回收内存所分成的情况,以及考虑发生OOM的情况进行gc


强引用: 不用举例子,平时new引用的对象就是强引用
软引用: 可以通过SoftReference<Obj> sr = new SoftReference<Obj>(obj);进行引用,
弱引用: 通过WeakReference<String> sr = new WeakReference<String>(new String("hello"));这个例子使用new创建对象为了避免对象在常量池中。
虚引用: 主要用来跟踪对象被垃圾回收的活动(GCRoot中的引用链应该就是用这个做的,如果一个对象没有被引用GCRoot引用到,则说明这是一个内存垃圾,需要进行垃圾回收)


虚引用的使用例子:

ReferenceQueue<String> queue = new ReferenceQueue<String>();
PhantomReference<String> pr = new PhantomReference<String>(new String("hello"), queue);