每天一篇系列:
强化知识体系,查漏补缺。
欢迎指正,共同学习!
在GC回收中提及到了弱引用,那强引用、软引用、弱引用、虚引用各有什么区别?
从Java SE2开始,就提供了四种类型的引用:强引用、软引用、弱引用和虚引用。
两个目的:
1.让程序员决定对象的生命周期
2.方便虚拟机垃圾回收
a)强引用(StrongReference)
强引用就是指在程序代码之中普遍存在的,比如下面这段代码中的object和str都是强引用:
Object object = new Object();
String str = "hello";
只要某个对象有强引用与之关联,JVM必定不会回收这个对象,即使在内存不足的情况下,JVM宁愿抛出OutOfMemory错误也不会回收这种对象
如果想中断强引用和某个对象之间的关联,可以显示地将引用赋值为null,这样一来的话,JVM在合适的时间就会回收该对象
b)软引用(SoftReference)
软引用是用来引用有用但是又不是必须的对象,当内存不足的时候,虚拟机会回收这些对象,比如在网页缓存、图片缓存时可以用这种特性有效的防止OOM。
软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被JVM回收,这个软引用就会被加入到与之关联的引用队列中:
import java.lang.ref.SoftReference;
public class Main {
public static void main(String[] args) {
SoftReference<String> sr = new SoftReference<String>(new String("hello"));
System.out.println(sr.get());
}
}
c)弱引用
弱引用也是用来描述非必需对象的,当JVM进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象
import java.lang.ref.WeakReference;
public class Main {
public static void main(String[] args) {
WeakReference<String> sr = new WeakReference<String>(new String("hello"));
System.out.println(sr.get());
System.gc(); //通知JVM的gc进行垃圾回收
System.out.println(sr.get());
}
}
d)虚引用
如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收
虚引用的作用是就跟踪对象被垃圾回收的状态,程序可以通过检测与虚引用关联的虚引用队列是否已经包含了指定的虚引用,从而了解虚引用的对象是否即将被回收
public static void main(String[] args){
// 创建一个对象
String str = new String("test");
//创建一个引用队列
ReferenceQueue<String> rq = new ReferenceQueue<String>();
//创建一个虚引用,指定引用对象.不能单独使用必须关联引用队列
PhantomReference pr = new PhantomReference(str,rq);
//切断强引用
str =null;
//试图取得虚引用对象
System.out.println(pr.get());
//垃圾回收
System.gc();
System.runFinalization();
//取出引队列中的最先进入队列的引用与pr进行比较
System.out.println(rq.poll()==pr);
}
在使用软引用和弱引用的时候,我们可以显示地通过System.gc()来通知JVM进行垃圾回收,但是要注意的是,虽然发出了通知,JVM不一定会立刻执行,也就是说这句是无法确保此时JVM一定会进行垃圾回收的。