前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java (强/弱/软/虚)引用

Java (强/弱/软/虚)引用

作者头像
Java架构师必看
发布2021-05-14 16:08:30
2240
发布2021-05-14 16:08:30
举报
文章被收录于专栏:Java架构师必看

一、整体架构


二、强引用(默认支持)


当内存不足,JVM 开始垃圾回收,对于强引用的对象,就算是出现了 OOM 也不会对该对象进行回收,死都不收。强引用是我们最常见的普通对象引用,只要还有强引用指向一个对象,就能表明对象还“活着”,垃圾回收器不会碰这种对象。在Java 中最常见的就是强引用,把一个对象赋给一个引用变量,这个引用变量就是一个强引用。当一个对象被强引用变量引用时,它处于可达状态,它是不可能被垃圾回收机制回收的,即使该对象以后永远都不会被用到 JVM 也不会回收。因此强引用是造成内存泄漏的主要原因之一。对于一个普通对象,如果没有其他引用关系,只要超过引用的作用域或者显示地将强应用设置为null,一般就可以被垃圾收集。(当然具体回收时机是要看垃圾收集策略)。

代码语言:javascript
复制
public class ReferenceDemo {
    public static void main(String[] args) {
        //o1 强引用(默认)
        Object o1 = new Object();
        //o2 引用赋值
        Object o2 = o1;
        //将o1 置为null
        o1 = null;
        //触发垃圾回收,回收o1
        System.gc();
        //查看 o2 是否有变化
        //输出结果:java.lang.Object@5305068a  说明o2 没有被回收,属于强引用
        System.out.println(o2);
    }
}

三、软引用


软引用是一种相对强引用弱化了一些的引用,需要用 java.lang.ref.SoftReference 类来实现,可以让对象豁免一些垃圾收集。对于弱引用来说: 【1】当系统内存充足时它不会被回收;

代码语言:javascript
复制
public class ReferenceDemo {
    public static void main(String[] args) {
        //o1 强引用(默认)
        Object o1 = new Object();
        //o2 引用赋值  ************重点***************
        SoftReference<Object> softReference = new SoftReference<>(o1);
        //java.lang.Object@5305068a
        System.out.println(o1);
        //将o1 置为null
         o1 = null;
        //触发垃圾回收,回收o1
        System.gc();
        //查看 o2 是否有变化
        //输出结果:java.lang.ref.SoftReference@5305068a  说明softReference 没有被回收,因为内存充足
        System.out.println(softReference.get());
        //输出结果:null
        System.out.println(o1);
    }
}

2】当系统内存不充足时它会被回收;代码演示:准备工作,设置内存大小为10m,具体配置如下:

代码语言:javascript
复制
@org.junit.Test
public void softReference(){
    //o1 强引用(默认)
    Object o1 = new Object();
    //o2 引用赋值
    SoftReference<Object> softReference = new SoftReference<>(o1);
    //将o1 置为null
    o1 = null;
    try {
        //模拟内存不足,我们通过 Xms和Xmx分配10M 的内存
        byte[] bytes = new byte[20*1024*1024];
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        //通过get 方法获取应用对象,输出结果为:null 说明内存不足时对此进行了回收
        System.out.println(softReference.get());
    }
}

软引用通常用于对内存敏感的程序中,比如高速缓冲就有用到软引用,内存够用的时候就保留,不够就回收!

四、弱引用


弱引用需要用 java.lang.ref.WeakReference 类实现,它比软引用的生存期更短,对于只有软引用的对象来说,只要垃圾回收机制一运行,不管JVM 内存是否足够,都会回收该对象占用的内存。

代码语言:javascript
复制
@org.junit.Test
public void weakReference(){
    //o1 强引用(默认)
    Object o1 = new Object();
    //o2 引用赋值
    WeakReference<Object> weakReference = new WeakReference<>(o1);
    //输出结果:java.lang.Object@1b701da1
    System.out.println(weakReference.get());
    //将o1 置为null
    o1 = null;
    System.gc();
    //通过get 方法获取应用对象,输出结果为:null 说明只要进行过gc 就可能被回收
    System.out.println(weakReference.get());
}

五、虚引用


虚引用需要 java.lang.ref.PhantomReference 类来实现。顾名思义,就是形同虚设,与其它几种引用不同,虚引用并不会决定对象的声明周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收,它不能单独使用也不能通过它访问对象,虚引用必须和引用队列(ReferenceQueue)联合使用。

虚引用的主要作用是跟踪对象被垃圾回收的状态,仅仅是提供一种确保对象被 finalize 以后,做某些事情的机制。PhantomReference 的 get方法总是返回 null,因此无法访问对应的引用对象。其意义在于说明一个对象已经进入 finalization 阶段,可以被 gc 回收,用来实现比 finalization 机制更灵活的回收操作。

换句话说,设置虚拟引用的唯一目的,就是在这个对象被收集器回收的时候收到一个系统通知或者后续添加进一步处理。Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。

代码语言:javascript
复制
@org.junit.Test
public void phantomReference(){
    //o1 强引用(默认)
    Object o1 = new Object();
    //引用队列
    ReferenceQueue referenceQueue = new ReferenceQueue();
    //创建虚引用
    PhantomReference phantomReference = new PhantomReference<>(o1, referenceQueue);
    System.out.println("GC 之前===================");
    System.out.println("o1 = "+o1);
    System.out.println("phantomReference = "+phantomReference.get());
    System.out.println("referenceQueue = "+referenceQueue.poll());

    //垃圾回收
    o1=null;
    System.gc();

    System.out.println("GC 之后===================");
    System.out.println("o1 = "+o1);
    System.out.println("phantomReference = "+phantomReference.get());
    System.out.println("referenceQueue = "+referenceQueue.poll());
}

输出结果展示:

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、整体架构
  • 二、强引用(默认支持)
  • 三、软引用
  • 四、弱引用
  • 五、虚引用
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档