Java引用类型:强引用,软引用,弱引用,虚引用
在Java中提供了4个级别的引用:强引用,软引用,弱引用,虚引用,使程序能更加灵活地控制对象的生命周期。在这4个引用级别中,只有强引用FinalReference类是包内可见,其他3中引用类型均为public,可以在应用程序中直接使用。
强引用
Java中的引用,有点像C++的指针,通过引用,可以对堆中的对象进行操作。 在我们的代码生涯中,大部分使用的都是强引用,所谓强引入,都是形如Object o = new Object()的操作。 强引用具备一下特点:
-
强引用可以直接访问目标对象 强引用所指向的对象在任何时候不会被系统回收,JVM宁愿抛出OOM异常,也不回收强引用所指向的对象 强引用可能导致内存泄漏
通常来说,应用程序内部的内存泄露有两种情况。一种是虚拟机中存在程序无法使用的内存区域,另一种情况是程序中存在大量存活时间过长的对象。
软引用
软引用是除强引用外,最强的引用类型。可以通过java.lang.ref.SoftReference使用软引用,一个持有软引用的对象,不会被JVM很快回收,JVM会根据当前堆的使用情况来判断何时回收,当堆使用率临近阈值时,才会去回收软引用对象。只要有足够的内存,软引用便可能在内存中存活相当长一段时间。因此,软引用可以用于实现对内存敏感的Cache。 在java doc中,软引用是这样描述的
虚拟机在抛出 OutOfMemoryError 之前会保证所有的软引用对象已被清除。此外,没有任何约束保证软引用将在某个特定的时间点被清除,或者确定一组不同的软引用对象被清除的顺序。不过,虚拟机的具体实现会倾向于不清除最近创建或最近使用过的软引用。
弱引用
弱引用时一种比软引用较弱的引用类型。在系统GC时,只要发现弱引用,不管系统对空间是否足够,都会对对象进行回收。但是,由于垃圾回收器的线程通常优先级很低,因此,并不一定能很快地发现持有弱引用的对象。在这种情况下,弱引用对象可以存在较长时间。一旦一个弱引用对象被垃圾收集器回收,便会加入导一个注册引用队列中
虚引用
虚引用时所有引用类型中最弱的一个,一个持有弱引用的对象,和没有引用几乎是一样的,随时都可能被垃圾回收器回收。当试图通过虚引用的get()方法取得强引用时,总会失败。并且,虚引用必须和引用队列一起使用,它的作用在于跟踪垃圾回收过程。当垃圾回收器准备回收一个对象时,如果发现他还有虚引用,就会在垃圾回收后销毁这个对象,将这个对象加入引用队列。虚引用主要用于检测对象是否已经从内存中删除。
SoftReference<String> stringSoftReference = new SoftReference<>(new String("软 引用 仔"));
System.out.println(stringSoftReference.get());
System.gc();
System.out.println(stringSoftReference.get());
//弱引用
WeakReference<String> str = new WeakReference<>("弱reference 森");
System.out.println(str.get());
System.gc(); //通知JVM进行内存回收
System.out.println(str.get());
//虚引用
ReferenceQueue<Object> queue = new ReferenceQueue<>();
PhantomReference<String> strs = new PhantomReference<>("虚引用 ", queue);
System.out.println(strs.get());
System.out.println(S);
四种引用的区别:
