强引用(Strong Reference)
永远不会被垃圾回收器回收,即使内存不足,JVM也会直接抛出OutOfMemoryError,不会去回收。如果想中断强引用与对象之间的联系,可以显示的将强引用赋值为null,这样一来,JVM就可以适时的回收对象了。
我们日常代码中创建的对象都属于强引用对象:
例如:
Person p=new Person();
p=null //显示设置为软引用
软引用(SoftReference)
当垃圾回收器发现软引用对象时,不会立即进行回收,而是标记该对象。软引用可以和一个引用队列联合使用,当内存空间不足时,才会进行回收,并且将该对象的引用放到引用队列中。
例如:
SoftReference<String> sr = new SoftReference<String>(new String("hello"));
System.out.println(sr.get());
弱引用(WeakReference)
当垃圾回收器发现弱引用时,会立即进行回收(此次扫描结束),不管内存够不够。弱引用可以和一个引用队列联合使用,当对象被回收时,JVM虚拟机会将该对象的引用放入引用队列中。
例如:
WeakReference<String> sr = new WeakReference<String>(new String("hello"));
System.out.println(sr.get());
System.gc(); //通知JVM的gc进行垃圾回收
System.out.println(sr.get());
输出结果:
hello
null
虚引用(PhantomReference)
随时可能被回收,必须和引用队列关联。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之 关联的引用队列中。
ReferenceQueue<String> queue = new ReferenceQueue<String>();
PhantomReference<String> pr = new PhantomReference<String>(new String("hello"), queue);
System.out.println(pr.get());
输出结果:
null
引用队列(ReferenceQueue)
ReferenceQueue中保存的对象是Reference对象,而且是已经失去了它所引用的对象的Reference对象。另外从ReferenceQueue这个名字也可以看出,它是一个队列,当我们调用它的poll()方法的时候,如果这个队列中不是空队列,那么将返回队列前面的那个Reference对象。
在任何时候,我们都可以调用ReferenceQueue的poll()方法来检查是否有它所关心的非强可及对象被回收。如果队列为空,将返回一个null,否则该方法返回队列中前面的一个Reference对象。利用这个方法,我们可以检查哪个SoftReference所引用的对象已经被回收。
ReferenceQueue<String> queue = new ReferenceQueue<String>();