Java (强/弱/软/虚)引用
一、整体架构

二、强引用(默认支持)
当内存不足,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 (强/弱/软/虚)引用的更多相关文章
- 0030 Java学习笔记-面向对象-垃圾回收、(强、软、弱、虚)引用
垃圾回收特点 垃圾:程序运行过程中,会为对象.数组等分配内存,运行过程中或结束后,这些对象可能就没用了,没有变量再指向它们,这时候,它们就成了垃圾,等着垃圾回收程序的回收再利用 Java的垃圾回收机制 ...
- Java:对象的强、软、弱、虚引用
转自: http://zhangjunhd.blog.51cto.com/113473/53092 1.对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无 ...
- Java中四种引用:强、软、弱、虚引用
这篇文章非常棒:http://alinazh.blog.51cto.com/5459270/1276173 Java中四种引用:强.软.弱.虚引用 1.1.强引用当我们使用new 这个关键字创建对象时 ...
- Java:对象的强、软、弱和虚引用
1.对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有对象处于可触及(reachable)状态,程序才能使用它.从JDK ...
- Java对象的强、软、弱和虚引用详解
1.对象的强.软.弱和虚引用 转自:http://zhangjunhd.blog.51cto.com/113473/53092/ 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无 ...
- java基础知识再学习--集合框架-对象的强、软、弱和虚引用
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://zhangjunhd.blog.51cto.com/113473/53092 本文 ...
- Java对象的强、软、弱和虚引用原理+结合ReferenceQueue对象构造Java对象的高速缓存器
//转 http://blog.csdn.net/lyfi01/article/details/6415726 1.Java对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变 ...
- Java:对象的强、软、弱和虚引用[转]
原文链接:http://zhangjunhd.blog.51cto.com/113473/53092/ 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法 ...
- Java对象的强、软、弱和虚引用+ReferenceQueue
Java对象的强.软.弱和虚引用+ReferenceQueue 一.强引用(StrongReference) 强引用是使用最普遍的引用.如果一个对象具有强引用,那垃圾回收器绝不会回收它.当内存空间不足 ...
- Java:对象的强、软、弱和虚引用的区别
1.对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有对象处于可触及(reachable)状态,程序才能使用它.从JDK ...
随机推荐
- 搭建 vue 项目
前提 : node 环境 也可以用 cnpm (淘宝镜像 npm install -g cnpm –registry=https://registry.npm.taobao.org) 全局安装vu ...
- 如何使用autotools/automake自动生成Makefile文件
前言: Linux下编程时,为了方便编译,往往使用Makefile文件自动完成编译,但是Makefile文件本身的书写十分复杂,规则很多.好在Linux为我们提供了自动生成功能完善的Makefile文 ...
- Communications link failure:The last packet successfully received from the server was 0 millisecond ago
出现这种错误的大致情况如下: 1.数据库连接长时间未使用,断开连接后,再去连接出现这种情况.这种情况常见于用连接池连接数据库出现的问题 2.数据库连接的后缀参数问题 针对上述两种情况,解决方案如下 1 ...
- AutoCAD_2020_Simplified_Chinese_Win_64bit_dlm
「AutoCAD_2020_Simplified_Chinese_Win_64bit_dlm」https://www.aliyundrive.com/s/zN8zAGgXZ58 点击链接保存,或者复制 ...
- JAVA设计模式及其设计原则
设计模式: 设计模式是一套被反复使用的.多数人知晓的.经过分类编目的.代码设计经验的总结. 单例模式:在一个jvm虚拟机,要创建的对象控制成独一份:举例:统计单台虚拟机内的用户在线数 package ...
- 在uni-app中调用高德地图去导航
1.判断一下是不是在微信环境 2.微信环境调用微信自带的地图导航 3.h5环境跳转去高德地图 guide() { let self = this; console.log("self.lat ...
- heimaJava17
java IO流 缓冲流 概念 缓存流也称为高效流.或者高级流.之前学习的字节流也可以称为原始流 作用:缓冲流自带缓冲区.可以提高原始字节流.字符流读写数据的性能 分类 字节缓冲流 字节缓冲输入流:B ...
- 网页返回unicode源码 python解码详细步骤
刚入门python! 记录一下网页返回源码,中文部分被unicode编码,python如何处理 1.先提取编码后的数据(如果不提取正篇源码直接unicode解码,解码方法无法识别) 这个步骤属于逻辑问 ...
- Connect to D365 CE with multi-factor Authentication using C# sharp
Effective Feb 4, 2020 - Use of the WS-Trust (Web-Service Trust) authentication security protocol whi ...
- Java基础学习——复利计算
面对一个问题的时候,首先应该确定问题中存在多少参数,对每个参数进行定义.并知晓所写代码目标.思路清晰,