Bootstrap

Java引用类型

Java中提供了4种引用类型,强引用、软引用、弱引用、虚引用。只有强引用FinalReference类是包内可见,其他三种均是public,可以直接在应用程序中直接使用。


一、强引用

Java的引用类似C中指针操作,C语言指针 ,通过引用,可以对Java堆内存中的对象进行操作。Java内存模型

StringBuffer stringBuffer = new StringBuffer("Helloword");

变量str指向了StringBuffer实例所在的堆空间,通过str可以操作这个对象。
强引用特点:

  1. 强引用可以直接访问目标对象。
  2. 强引用所在指向的对象在任何时候都不会被系统回收,JVM宁愿抛出OOM异常,也不会回收强引用所指向的对象。
  3. 强引用可能导致内存泄漏。

二、软引用

软引用是仅次于强引用之外,最强的引用类型,可以通过java.lang.ref.SoftReference使用软引用。持有软引用的对象,不会被JVM,很快回收,JVM会根据当前堆的使用情况来判定何时回收。
若堆使用率接近临界值,则回收软引用对象,可以利用这点实现对内存敏感的高速缓存。
SoftReference特点就是它的一个实例保存了对一个Java对象的软引用,该软引用的存在并不妨碍GC线程对该对象的回收。
设置IDEA堆内存大小为2M:

    @Test    
   public void test3(){
        MyObject obj = new myObject();
        SoftReference sf = new SoftReference<>(obj);
        obj = null;
        System.gc();//        byte[] bytes = new byte[1024*100];//        System.gc();
        System.out.println("是否被回收"+sf.get());
    }

结果:

是否被回收cn.zyzpp.MyObject@42110406

打开注释的new byte[1024 * 100]语句,这条语句请求一条更大的堆空间,让堆内存紧张,显式调用GC,结果如下:

是否被回收null

表明软引用被系统回收。


三、弱引用

软引用,弱引用都非常适合保存那些可有可无的缓存数据,若这么做,则系统内存不足时,这些缓存数据会被回收,不会导致内存溢出。而当内存资源充足时,这些缓存数据又可以存在相当长时间,起到系统加速作用。

弱引用在GC时,只要发现弱引用存在,不管系统堆空间是否充足,都会立刻回收对象:

    public void test3(){
        MyObject obj = new MyObject();
        WeakReference sf = new WeakReference(obj);
        obj = null;
        System.out.println("是否被回收"+sf.get());
        System.gc();
        System.out.println("是否被回收"+sf.get());
    }

四、虚引用

一个持有虚引用的对象,和没有引用几乎一样,随时会被垃圾回收GC,若试图通过虚引用get方法取得强引用,总是失败,并且虚引用和引用队列一起使用,它的作用在于跟踪GC过程。

当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在垃圾回收后,销毁这个对象,将这个虚引用加入引用队列。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动:

   public void test3(){
        MyObject obj = new MyObject();
        ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
        PhantomReference sf = new PhantomReference<>(obj,referenceQueue);
        obj = null;
        System.out.println("是否被回收"+sf.get());
        System.gc();
        System.out.println("是否被回收"+sf.get());
    }

对虚引用执行get方法:总是返回null。

    public T get() {        
       return null;
    }

Java引用类型

;