一、整体架构


二、强引用(默认支持)


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

 1 public class ReferenceDemo {
2 public static void main(String[] args) {
3 //o1 强引用(默认)
4 Object o1 = new Object();
5 //o2 引用赋值
6 Object o2 = o1;
7 //将o1 置为null
8 o1 = null;
9 //触发垃圾回收,回收o1
10 System.gc();
11 //查看 o2 是否有变化
12 //输出结果:java.lang.Object@5305068a 说明o2 没有被回收,属于强引用
13 System.out.println(o2);
14 }
15 }

三、软引用


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

 1 public class ReferenceDemo {
2 public static void main(String[] args) {
3 //o1 强引用(默认)
4 Object o1 = new Object();
5 //o2 引用赋值 ************重点***************
6 SoftReference<Object> softReference = new SoftReference<>(o1);
7 //java.lang.Object@5305068a
8 System.out.println(o1);
9 //将o1 置为null
10 o1 = null;
11 //触发垃圾回收,回收o1
12 System.gc();
13 //查看 o2 是否有变化
14 //输出结果:java.lang.ref.SoftReference@5305068a 说明softReference 没有被回收,因为内存充足
15 System.out.println(softReference.get());
16 //输出结果:null
17 System.out.println(o1);
18 }
19 }

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

 1 @org.junit.Test
2 public void softReference(){
3 //o1 强引用(默认)
4 Object o1 = new Object();
5 //o2 引用赋值
6 SoftReference<Object> softReference = new SoftReference<>(o1);
7 //将o1 置为null
8 o1 = null;
9 try {
10 //模拟内存不足,我们通过 Xms和Xmx分配10M 的内存
11 byte[] bytes = new byte[20*1024*1024];
12 }catch (Exception e){
13 e.printStackTrace();
14 }finally {
15 //通过get 方法获取应用对象,输出结果为:null 说明内存不足时对此进行了回收
16 System.out.println(softReference.get());
17 }
18 }

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

四、弱引用


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

 1 @org.junit.Test
2 public void weakReference(){
3 //o1 强引用(默认)
4 Object o1 = new Object();
5 //o2 引用赋值
6 WeakReference<Object> weakReference = new WeakReference<>(o1);
7 //输出结果:java.lang.Object@1b701da1
8 System.out.println(weakReference.get());
9 //将o1 置为null
10 o1 = null;
11 System.gc();
12 //通过get 方法获取应用对象,输出结果为:null 说明只要进行过gc 就可能被回收
13 System.out.println(weakReference.get());
14 }

五、虚引用


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

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

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

 1 @org.junit.Test
2 public void phantomReference(){
3 //o1 强引用(默认)
4 Object o1 = new Object();
5 //引用队列
6 ReferenceQueue referenceQueue = new ReferenceQueue();
7 //创建虚引用
8 PhantomReference phantomReference = new PhantomReference<>(o1, referenceQueue);
9 System.out.println("GC 之前===================");
10 System.out.println("o1 = "+o1);
11 System.out.println("phantomReference = "+phantomReference.get());
12 System.out.println("referenceQueue = "+referenceQueue.poll());
13
14 //垃圾回收
15 o1=null;
16 System.gc();
17
18 System.out.println("GC 之后===================");
19 System.out.println("o1 = "+o1);
20 System.out.println("phantomReference = "+phantomReference.get());
21 System.out.println("referenceQueue = "+referenceQueue.poll());
22 }

输出结果展示:
 

 

Java (强/弱/软/虚)引用的更多相关文章

  1. 0030 Java学习笔记-面向对象-垃圾回收、(强、软、弱、虚)引用

    垃圾回收特点 垃圾:程序运行过程中,会为对象.数组等分配内存,运行过程中或结束后,这些对象可能就没用了,没有变量再指向它们,这时候,它们就成了垃圾,等着垃圾回收程序的回收再利用 Java的垃圾回收机制 ...

  2. Java:对象的强、软、弱、虚引用

    转自: http://zhangjunhd.blog.51cto.com/113473/53092 1.对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无 ...

  3. Java中四种引用:强、软、弱、虚引用

    这篇文章非常棒:http://alinazh.blog.51cto.com/5459270/1276173 Java中四种引用:强.软.弱.虚引用 1.1.强引用当我们使用new 这个关键字创建对象时 ...

  4. Java:对象的强、软、弱和虚引用

    1.对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有对象处于可触及(reachable)状态,程序才能使用它.从JDK ...

  5. Java对象的强、软、弱和虚引用详解

    1.对象的强.软.弱和虚引用 转自:http://zhangjunhd.blog.51cto.com/113473/53092/ 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无 ...

  6. java基础知识再学习--集合框架-对象的强、软、弱和虚引用

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://zhangjunhd.blog.51cto.com/113473/53092 本文 ...

  7. Java对象的强、软、弱和虚引用原理+结合ReferenceQueue对象构造Java对象的高速缓存器

    //转 http://blog.csdn.net/lyfi01/article/details/6415726 1.Java对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变 ...

  8. Java:对象的强、软、弱和虚引用[转]

    原文链接:http://zhangjunhd.blog.51cto.com/113473/53092/ 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法 ...

  9. Java对象的强、软、弱和虚引用+ReferenceQueue

    Java对象的强.软.弱和虚引用+ReferenceQueue 一.强引用(StrongReference) 强引用是使用最普遍的引用.如果一个对象具有强引用,那垃圾回收器绝不会回收它.当内存空间不足 ...

  10. Java:对象的强、软、弱和虚引用的区别

    1.对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有对象处于可触及(reachable)状态,程序才能使用它.从JDK ...

随机推荐

  1. px 转化 为 rpx

    小程序 的 px 转化为rpx 在 获取 屏幕高度 后 ,这个单位是px ,可是我的项目是用rpx,所以这里就涉及一个转化的公式了 1rpx = 750 / 设备屏幕宽度 所以 wx.getSyste ...

  2. vantUI <van-uploader> 上传图片,如何获取图片的尺寸

    html代码 <van-uploader preview-size="300px" style="width:300px;display:block;margin: ...

  3. web3招聘信息渠道

    [web3招聘信息渠道]随手转发,供参考,供补充. 个人微博:https://weibo.com/u/2434823180 Blog: https://apenote.github.io vx: ap ...

  4. java pta第二次阶段性总结

    一.前言 经过这三次的pta训练,我对java再一次有了一个新的认识,这三次比起之前难度更大,所涉及的知识点更多.第4.5次作业是在前几次作业上的再次拓展,由三角形拓展到四边形,再由四边形拓展到五边形 ...

  5. Element UI 父组件el-tabel选择某行跳转子组件,在子组件的el-table中选择数组,添加到父组件操作行中

    解决思路: 1.在父组件选择操作某行数据时,将父组件的行号暂存(index). 2.跳转子组件页面,选择某行数据,点击提交将该行数据传递个父组件 3.父组件取到第一步暂存行号(index),将子组件传 ...

  6. uniapp中使用echarts点击图例与tooltips无反应

    只需要在项目main.js文件中加上 window.wx = {} // echarts中tooltips点击无反应与点击图例无反应解决方法 即可

  7. 【转载】Python 在已存在的excel表格中写入数据

    由于每天都要汇总日报数据,其实就是个复制粘贴的工作,将多个表的数据汇总成一个表格,工作较枯燥,于是想到用Python帮我完成这个简单又粗糙的工作.写一下我学到的几个小技巧,下次忘记怎么使用的时候,还能 ...

  8. 字典方法 setdefault()、pprint;迭代、递归的区别

    计算一个字符串中每个字符出现的次数 import pprint message = 'It was a bright cold day in April, ' \ 'and the clocks we ...

  9. 导入ssm项目时,项目基本的配置文件

    一.ssm框架基本的配置文件 上面的这些配置文件对于比较简单的ssm项目其实大同小异,逻辑上是差不多的. 在config目录下 在lib下就是各种jar包 二.导入ssm项目后,本地环境配置和项目本身 ...

  10. springBoot 这货特别火

    现在 Spring Boot 非常火,各种技术文章,各种付费教程,多如牛毛,可能还有些不知道 Spring Boot 的,那它到底是什么呢?有什么用?今天给大家详细介绍一下. Spring Boot ...