Java的几种引用类型

概述

Java里存在四种类型的引用:强引用、软引用、弱引用和虚引用

这四种引用类型,可以让我们决定对象的生命周期,利于JVM的GC回收,进而对内存溢出和内存泄漏可以有更好的解决途径。



Java的几种引用类型与可达性

引用类型 可达性 存在方式 GC回收方式
强可达 强引用 在一个线程内,无需引用直接可达 在引用存在的情况下不会回收
软可达 软引用 通过SoftReference对象可达 内存不足时,根据使用频率进行清除
弱可达 弱引用 通过WeakReference对象可达 当GC调用时,必定被回收
虚可达 虚引用 通过PhantomReference对象可达 不影响生命周期
不可达 不存在 没有任何途径可达 调用即清除



强引用(Strong Reference)

  • 强引用是最常用的引用,只要引用存在,就不会被回收。
  • 只有在堆上的对象实例不存在任何引用指向它的时候,才会被回收。
  • 若想让一个对象实例的空间释放,就应该关闭所有引用(赋予null)
String str = new String("This is a Strong Reference");//强引用

str = null; 
System.gc(); //通知gc进行回收

通常我们不需要手动调用gc进行回收,系统会自动进行,这里仅仅只是作为演示。还需要注意的是:System.gc()仅仅只是通知gc进行回收,并非会立即执行



软引用(Soft Reference)

  • 软引用可以用来引用一些不那么重要的对象,可以是一些易失对象。
  • 软引用的对象实例,只有在内存不足的时候JVM才会根据使用频率进行回收
  • 在Java中用java.lang.ref.SoftReference类来表示
  • 灵活使用软引用可以解决很多OOM(OutOfMemory)问题
  • 应用场景:图片缓存,网页缓存 …
1)不使用引用队列
SoftReference<String> sr = new SoftReference<String> (new String("Soft Reference"));
System.gc();
System.out.println(sr.get());

2)使用引用队列
ReferenceQueue<String> Queue = new ReferenceQueue<String>();
SoftReference<String> sr = new SoftReference<String> (new String("Soft Reference"),Queue);
System.gc();
System.out.println(sr.get());

可以选择添加引用队列,这样一旦软引用的对象实例被 JVM回收,这个软引用就会被加入到与之关联的引用队列中



弱引用(WeakReference)

  • 弱引用通常是用来作为临时引用
  • 弱引用的对象实例,只要是系统调用gc回收的时候,必定会被清理
  • java.lang.ref.WeakReference类来表示
WeakReference<String> wr = new WeakReference<String>(new String("Weak Reference"));
System.gc();
System.out.println(wr.get());



虚引用(PhantomReference)

唯一目的就是能在这个对象被回收时收到一个系统通知,虚引用主要用于检测对象是否已经从内存中删除

  • 虚引用是用于检测对象是否已经从内存中删除,仅仅只有一个虚引用的对象是没有意义的,会被gc进行回收。
  • 和软引用和弱引用不同的是,它不会对对象的生命周期造成影响
  • 虚引用一定要与引用队列一同使用
String str = new String("This is a Phantom Reference")
ReferenceQueue<String> Queue = new ReferenceQueue<String>();
PhantomReference<String> pr = new PhantomReference<String>(str,Queue);
str = null;
System.gc();
System.out.println(pr.isEnqueued());//判断是否已经被回收

你可能感兴趣的:(java基础)