JAVA对象的四种引用方式

一、前言:

JVM是通过GC机制自动回收内存空间的,不同于c++手动释放空间,在JAVA中设置不同的引用方式就是为了让jvm虚拟机去判断哪些对象应该释放,而哪些对象不能释放.从而使程序更加灵活的控制对象的生命周期。

四种引用级别的高低顺序---(高到底)----->强引用,软引用,弱引用,虚引用;

二 、强引用

(一)含义

创建一个对象,并把这个对象赋值给一个引用变量。

Object obj =new Object();
String str ="hello world!";

如上所示,就是我们平时创建对象的案例,这两个引用变量都属于强引用,当此对象被强引用所指向时,JVM永远不会对其回收。且当内存空间不足 抛出OutOfMemoryError错误 ,使程序异常终止,也不会靠回收具有强引用的对象,来解决内存不足的问题。

(二)回收强引用对象

可以显式地将引用赋值为null,这样的话JVM就会在合适的时间,进行垃圾回收

三、软引用(SoftReference)

(一)含义

一个对象如果是软引用,当堆内存足够时,垃圾回收器就不会对其进行回收,只有在内存空间不足,要迫切释放空间的时候,jvm才会释放软引用的对象。在软引用对象被回收之前,这些对象就可以被使用。 如图片缓存框架中缓存图片就是通过软引用实现

(二)代码分析

我们可以通过SoftReference关键字来软引用对象,它的一个实例保存对一个java对象的软引用 ,并利用其中提供的get()方法 去获取对象的地址;如果返回NULL,说明此对象被回收。

 public static void main(String[] args) {
          List> list = new ArrayList<>();
          for(int i=0; i<5; i++){
             SoftReference ref = new SoftReference<>(new byte[4*1024*1024]);
             
              list.add(ref);  //将软引用添加到集合中
           
        }
         System.out.println("循环结束:" + list.size());
         for(SoftReference ref : list){ 
             System.out.println(ref.get()); //依次遍历出每个软引用对象的地址 
                        //通过get获取它的地址
         }
     } 

注 : 在以上代码中设置JVM参数 使其堆的空间调为20M( 参数: -Xmx20m)

用一个list集合来保存byte数组,此数组大小为4M,且数组为软引用类型,利用for循环连续添加5次该数组,并在最后打印出list中存储的每个软引用对象

 结果如下图:

JAVA对象的四种引用方式_第1张图片

 说明在创建第五个软引用对象时,此时堆中的空间不足,GC便将之前的软应用对象回收掉,存放新的对象。所以,打印出的前四个均为空,只有最后生成的才有地址。

 四、弱引用(PhantomReference)

(一)注解

弱引用和软引用的区别在于:弱引用的对象拥有更短的生命周期,只要垃圾回收器扫描到它,不管内存空间充足与否,都会回收它的内存。 下面我们通过WeakReference类来说明:

 public static void main(String[] args) {

        WeakReference reference =new WeakReference(new People("弱引用"));
          System.out.println(reference.get());
          System.gc();//通知GVM回收资源
          System.out.println(reference.get());
     }
 }

(二)代码分析

代码结果:第一次的输出有对象的成员值,第二次输出为NULL。 说明调用了gc之后,弱引用对象reference被垃圾回收了,所以第二个输出语句输出null。

 注:如果存在强引用和弱引用同时关联一个对象,那么这个对象是不会被jvm回收的,这点和软引用相同。如:

//强引用和弱引用的关联引用
  People people = new People("关联");
  WeakReference reference = new WeakReference<>(people);

  System.out.println(reference.get());
  System.gc();//通知GVM回收资源
  System.out.println(reference.get());

即结果都是一样的,回收器不会回收次对象。

五、虚引用

(一)注解

简单来说就是对于引用对象来说如同虚设。如果一个对象仅持有虚引用,那么它和没有任何引用一样,在任何时候都有可能被垃圾回收器回收。

 (二)作用

主要用来跟踪对象被垃圾回收的活动。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。

 六、总结

我们平时用的最多的就是强引用,其次是软引用和弱引用,后两者一般用来描述非必需的对象,以此来控制对象的生命周期。软引用关联的对象只有在jvm堆内存不足时,才会被垃圾回收,而弱引用关联的对象在jvm进行垃圾回收的时候总会被回收。

你可能感兴趣的:(引用类型,JVM,java)