一、整体架构


二、强引用(默认支持)


当内存不足,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. IDEA-mybatis逆向工程使用

    首先我们需要安装mybatis逆向工程插件mybatis Generator: 然后在pom.xml文件中添加逆向工程插件: <!--mybatis逆向工程插件--> <plugin ...

  2. PHP Redis - 事务

    Redis 事务可以一次执行多个命令, 并有两个重要的保证: ① 事务是一个单独的隔离操作:事务中的所有命令都会序列化.按顺序地执行.事务在执行的过程中,不会被其他客户端发送来的命令请求所打断. ② ...

  3. 使用DockerCompose部署微服务项目(基于Springboot搭建一个简易计数器)

    准备Dockerfile FROM java:8 #基于jdk8的环境 COPY *.jar /app.jar #拷贝所有的jar包到/app.jar目录下 CMD ["--server.p ...

  4. axios取消重复请求与更新token并续订上次请求

    一.问题引入 当用户发起一个请求时,判断token是否已过期,若已过期则先调refreshToken接口,拿到新的token后再继续执行之前的请求. 难点:当同时发起多个请求,token 过期会调用多 ...

  5. pyahocorasick 安装和使用问题总结

    因系统中用到了ahocorasick,但是程序跑起来有BUG,故而10.1假期研究了一下,趟过几个坑,分享一下. 一.安装过程中的坑 直接安装pip install  pyahocorasick 是会 ...

  6. OO课程第二阶段(实验和期中试题)总结Blog2

    OO课程第二阶段(实验和期中试题)总结Blog2 前言:学习OOP课程的第二阶段已经结束了,在此进行对于知识点,题量,难度的个人看法. 学习OOP课程的第二阶段已经结束了,较第一次阶段学习难度加大,学 ...

  7. ArrayList 的toArray的转换数组方法的注意事项

    ArrayList 的toArray的转换数组方法的注意事项 toArray()一共有两个方法 toArray(T[] a) 和toArray() 源码是 进行使用toArray()方法时候,使用 ( ...

  8. thymeleaf基础学习

    Thymeleaf 1.标准表达式 ${...}:变量表达式 *{...}: 选择表达式 #{...} : 消息表达式 @{...}: 连接表达式 <img th:src="@{url ...

  9. Linux让部署在服务器上的项目一直保持运行状态…&跑多个项目

    在idea通过package得到的.jar包或者.war包可通过 java -jar xxx.jar/xxx.war 命令直接在linux或者windows系统运行:   将打好包的项目放在linux ...

  10. idea 改变片段内相同变量的快捷键

    在 win系统中 shift+F6 在 ios系统中Fn+shift+F6