1、强引用类型
2、弱引用
3、软引用
我们来举例说明下
package www.weiyuan.test; import java.lang.ref.SoftReference; import java.lang.ref.WeakReference; public class Test { public static void main(String[] args) { // TODO Auto-generated method stub
//创建了一个强引用类型 String str = "abc"; //创建一个软引用对象 SoftReference<String> sfr = new SoftReference<String>(str); //创建一个弱引用类型 WeakReference<String> wrf = new WeakReference<String>(str); } }
对象的可及性:一个对象可由多个变量来来引用,对象的可及性由最强引用类型来决定
上面对象adc有三个引用,一个是强可及,一个是软可及,还有一个是弱可及,最强引用是强可及
强可及对象永远不会被gcc垃圾回收器回收
软可及对象当系统内存不足的时候,gcc会把软可及对象回收掉
弱可及对象当gcc发现这个对象是弱可及对象就马上将对象回收
package www.weiyuan.test; import java.lang.ref.SoftReference; import java.lang.ref.WeakReference; public class Test { public static void main(String[] args) { // TODO Auto-generated method stub String str = "abc"; //创建一个软引用对象 SoftReference<String> sfr = new SoftReference<String>(str); //创建一个弱引用类型 WeakReference<String> wrf = new WeakReference<String>(str); //去除强可及str对象不再和adc对象存在任何关系 str = null; //通过软可及获得对象的值 String result1 = sfr.get(); //通过弱可及获得对象的值 String result2 = wrf.get(); System.out.println("result1 ="+result1); System.out.println("result2 ="+result1); } }
输出的结果是:
result1 =abc
result2 =abc
str = null;就是去掉str和对象"abc"的强可及关系,此时依然可以通过软引用和弱引用获得对象所关联的值
弱可及对象当gcc发现这个对象是弱可及对象就马上将对象回收
package www.weiyuan.test; import java.lang.ref.SoftReference; import java.lang.ref.WeakReference; public class Test { public static void main(String[] args) { // TODO Auto-generated method stub String str = "abc"; //创建一个软引用对象 SoftReference<String> sfr = new SoftReference<String>(str); //创建一个弱引用类型 WeakReference<String> wrf = new WeakReference<String>(str); //去除强可及str对象不再和adc对象存在任何关系 str = null; //清除软引用的引用链 sfr.clear(); //通过弱可及获得对象的值 String result2 = wrf.get(); //通过软可及获得对象的值 String result1 = sfr.get(); System.out.println("result1 ="+result1); System.out.println("result2 ="+result2); } }
我们使用
sfr.clear();去掉对象的软引用链接,这个时候对象的可及性是弱引用对象,清除之后通过软引用我们无法获得对象的值,但是依然可以通过弱引用获得对象的值,我们来看日志的打印输出
result1 =null
result2 =abc
在上面代码的基础上,我们知道当前对象的可及性是弱引用,我们收到调用gcc回收,看能否在获得对象的值
package www.weiyuan.test; import java.lang.ref.SoftReference; import java.lang.ref.WeakReference; public class Test { public static void main(String[] args) { // TODO Auto-generated method stub String str = "abc"; //创建一个软引用对象 SoftReference<String> sfr = new SoftReference<String>(str); //创建一个弱引用类型 WeakReference<String> wrf = new WeakReference<String>(str); //去除强可及str对象不再和adc对象存在任何关系 str = null; //清除软引用的引用链 sfr.clear(); //运行垃圾回收器 System.gc(); //通过弱可及获得对象的值 String result2 = wrf.get(); //通过软可及获得对象的值 String result1 = sfr.get(); System.out.println("result1 ="+result1); System.out.println("result2 ="+result2); } }
该对象已经是弱引用了,我们调用了系统的垃圾回收器,发现对象如果是弱引用,就立刻回收该对象的值
我们来看看日志的打印
result1 =null
result2 =abc
居然在垃圾回收器之后,居然还可以通过弱引用获得对象的值
这是为啥了,这里因为埋了一个坑
因为创建的对象
"abc"是存在在系统的常量池中的,我们使用gc是无法回收常量池中的对象的,gc只能回收堆内存中的弱引用对象
我们把
package www.weiyuan.test; import java.lang.ref.SoftReference; import java.lang.ref.WeakReference; public class Test { public static void main(String[] args) { // TODO Auto-generated method stub String str = new String("abc"); //创建一个软引用对象 SoftReference<String> sfr = new SoftReference<String>(str); //创建一个弱引用类型 WeakReference<String> wrf = new WeakReference<String>(str); //去除强可及str对象不再和adc对象存在任何关系 str = null; //清除软引用的引用链 sfr.clear(); //运行垃圾回收器 System.gc(); //通过弱可及获得对象的值 String result2 = wrf.get(); //通过软可及获得对象的值 String result1 = sfr.get(); System.out.println("result1 ="+result1); System.out.println("result2 ="+result2); } }
我们运行下代码:
result1 =null
result2 =null
通过new String的对象都是存在在堆内存中,所以我们使用gc就能够回收了。