Java 强引用,软引用,弱引用,虚引用

强引用

作为初学者,我们平时用的Object obj=new Object();就是强引用,这类引用在显示释放的时候才会为Null

Object strongReference = new Object();

只有当我们不使用这个对象,如下申明后才会被回收:

strongReference = null;

这里有几点需要注意:

  • 在一个方法的内部局部变量一个强引用,这个引用保存在Java栈中,而真正的引用内容(Object)保存在Java堆中。当这个方法运行完成后,就会退出方法栈,则引用对象的引用数为0,这个对象会被回收。而如果我们将其return;这个时候,调用者会形成新的强引用;
  • 但是如果这个方法中strongReference是全局变量时,不会被自动回收(大多情况下也不应该被回收)。
  • 对于一些集合,使用clear()将集合内部清空,而=null会让集合被释放
  • 对于下面代码,a=null只是说明a指向null不引用自己new出来的obj了,但是b还是引用着这个Obj;所以b最终不等于null
Obj a=new Obj();
b=a;
a=null;

强引用也是唯一可以一直存在直到手动释放的,下面三种引用的生命周期就不受自己控制了

软引用(SoftReference)

如果一个对象只具有软引用,那就类似于可有可无的生活用品。如果内存空间足够,垃圾回收器就不会回收它,如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。

ReferenceQueue<String> referenceQueue = new ReferenceQueue<>();
    String str = new String("abc");//str是abc强引用
    SoftReference<String> softReference = new SoftReference<>(str, referenceQueue);//softReference就是abc的弱引用
    str=null;//这个时候abc只有弱引用
    System.gc();

    System.out.println(softReference.get()); // abc
    //强行使弱引用失效,模拟内存不足
    Reference<? extends String> reference = referenceQueue.poll();
    System.out.println(reference); //null,当内存不足,上一步不需要执行,也会null

弱引用

弱引用与软引用只有一点区别:只具有弱引用的对象拥有更短暂的生命周期。
在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。(所以没扫描到前还是存活的)

        Object obj = new Object();
        WeakReference<Object> weakObj = new WeakReference<Object>(obj);
        obj=null;  //手动释放只剩下一个weakObj弱引用
        int i=0;

        while(true){
            if(weakObj.get()!=null){
                i++;
                System.out.println("Object is alive for "+i+" loops - "+weakObj);
            }else{
                System.out.println("Object has been collected.");
                break;
            }
        }
output:
Object is alive for 1 loops - java.lang.ref.WeakReference@4554617c
...
Object is alive for 29721 loops - java.lang.ref.WeakReference@4554617c
Object has been collected.
执行到第29721次被扫描到回收了

虚引用

这个就是个完全没发言权的弟弟,引用了只是为了跟踪对象的生命周期,一旦对象只有虚引用,那就直接GC了;

    String str = new String("abc");
    ReferenceQueue queue = new ReferenceQueue();
    // 创建虚引用,要求必须与一个引用队列关联
    PhantomReference pr = new PhantomReference(str, queue);
    str=null//这个时候直接GG
  • 总结
引用类型 被垃圾回收时间 用途 生存时间
强引用 从来不会 对象的一般状态 JVM停止运行时终止
软引用 当内存不足时 对象缓存 内存不足时终止
弱引用 正常垃圾回收时 对象缓存 垃圾回收后终止
虚引用 正常垃圾回收时 跟踪对象的垃圾回收 垃圾回收后终止

参考:
https://blog.csdn.net/junjunba2689/article/details/80601729
https://blog.csdn.net/baidu_22254181/article/details/82555485

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容