一、前言:
JVM是通过GC机制自动回收内存空间的,不同于c++手动释放空间,在JAVA中设置不同的引用方式就是为了让jvm虚拟机去判断哪些对象应该释放,而哪些对象不能释放.从而使程序更加灵活的控制对象的生命周期。
四种引用级别的高低顺序---(高到底)----->强引用,软引用,弱引用,虚引用;
二 、强引用
(一)含义
创建一个对象,并把这个对象赋值给一个引用变量。
Object obj =new Object();
String str ="hello world!";
如上所示,就是我们平时创建对象的案例,这两个引用变量都属于强引用,当此对象被强引用所指向时,JVM永远不会对其回收。且当内存空间不足 抛出OutOfMemoryError错误 ,使程序异常终止,也不会靠回收具有强引用的对象,来解决内存不足的问题。
(二)回收强引用对象
可以显式地将引用赋值为null,这样的话JVM就会在合适的时间,进行垃圾回收
。
三、软引用(SoftReference)
(一)含义
(二)代码分析
public static void main(String[] args) {
List<SoftReference<byte[]>> list = new ArrayList<>();
for(int i=0; i<5; i++){
SoftReference<byte[]> ref = new SoftReference<>(new byte[4*1024*1024]);
list.add(ref); //将软引用添加到集合中
}
System.out.println("循环结束:" + list.size());
for(SoftReference<byte[]> ref : list){
System.out.println(ref.get()); //依次遍历出每个软引用对象的地址
//通过get获取它的地址
}
}
注 : 在以上代码中设置JVM参数 使其堆的空间调为20M( 参数: -Xmx20m)
结果如下图:
四、弱引用(PhantomReference)
(一)注解
弱引用和软引用的区别在于:弱引用的对象拥有更短的生命周期,只要垃圾回收器扫描到它,不管内存空间充足与否,都会回收它的内存
。 下面我们通过WeakReference类来说明:
public static void main(String[] args) {
WeakReference<People> reference =new WeakReference<People>(new People("弱引用"));
System.out.println(reference.get());
System.gc();//通知GVM回收资源
System.out.println(reference.get());
}
}
(二)代码分析
注:如果存在强引用和弱引用同时关联一个对象,那么这个对象是不会被jvm回收的,这点和软引用相同。如:
//强引用和弱引用的关联引用
People people = new People("关联");
WeakReference<People> reference = new WeakReference<>(people);
System.out.println(reference.get());
System.gc();//通知GVM回收资源
System.out.println(reference.get());
即结果都是一样的,回收器不会回收次对象。