Java四大引用详解:强引用、软引用、弱引用、虚引用
Java引用
从JDK 1.2版本开始,对象的引用被划分为4种级别,从而使程序能更加灵活地控制对象的生命周期,这4种级别由高到低依次为:强引用、软引用、弱引用和虚引用。
强引用
强引用是最普遍的引用,一般把一个对象赋给一个引用变量,这个引用变量就是强引用。
比如:
// 强引用
MikeChen mikechen=new MikeChen();
在一个方法的内部有一个强引用,这个引用保存在Java栈中,而真正的引用内容(MikeChen)保存在Java堆中。
如果一个对象具有强引用,垃圾回收器不会回收该对象,当内存空间不足时,JVM 宁愿抛出 OutOfMemoryError异常。
如果强引用对象不使用时,需要弱化从而使GC能够回收,如下:
//帮助垃圾收集器回收此对象
mikechen=null;
显式地设置mikechen对象为null,或让其超出对象的生命周期范围,则GC认为该对象不存在引用,这时就可以回收这个对象,具体什么时候收集这要取决于GC算法。
举例:
显式地设置mikechen对象为null,或让其超出对象的生命周期范围,则GC认为该对象不存在引用,这时就可以回收这个对象,具体什么时候收集这要取决于GC算法。举例:
StrongRefenenceDemo 中尽管 o1已经被回收,但是 o2 强引用 o1,一直存在,所以不会被GC回收。
软引用
软引用是一种相对强引用弱化了一些的引用,需要用java.lang.ref.SoftReference 类来实现。
比如:
String str=new String("abc"); // 强引用
SoftReference<String> softRef=new SoftReference<String>(str); // 软引用
如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它,如果内存空间不足了,就会回收这些对象的内存。
先通过一个例子来了解一下软引用:
/**
* 弱引用举例
*
* @author mikechen
*/
Object obj = new Object();
SoftReference softRef = new SoftReference<Object>(obj);//删除强引用
obj = null;//调用gc// 对象依然存在
System.gc();System.out.println("gc之后的值:" + softRef.get());
软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用对象被垃圾回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。
ReferenceQueue<Object> queue = new ReferenceQueue<>();
Object obj = new Object();
SoftReference softRef = new SoftReference<Object>(obj,queue);//删除强引用
obj = null;//调用gc
System.gc();
System.out.println("gc之后的值: " + softRef.get()); // 对象依然存在
//申请较大内存使内存空间使用率达到阈值,强迫gc
byte[] bytes = new byte[100 * 1024 * 1024];//如果obj被回收,则软引用会进入引用队列
Reference<?> reference = queue.remove();if (reference != null){System.out.println("对象已被回收: "+ reference.get()); // 对象为null
}
软引用通常用在对内存敏感的程序中,比如高速缓存就有用到软引用,内存够用的时候就保留,不够用就回收。
我们看下 Mybatis 缓存类 SoftCache 用到的软引用:
public Object getObject(Object key) {Object result = null;SoftReference<Object> softReference = (SoftReference)this.delegate.getObject(key);if (softReference != null) {result = softReference.get();if (result == null) {this.delegate.removeObject(key);} else {synchronized(this.hardLinksToAvoidGarbageCollection) {this.hardLinksToAvoidGarbageCollection.addFirst(result);if (this.hardLinksToAvoidGarbageCollection.size() > this.numberOfHardLinks) {this.hardLinksToAvoidGarbageCollection.removeLast();}}}}return result;}
注意:软引用对象是在jvm内存不够的时候才会被回收,我们调用System.gc()方法只是起通知作用,JVM什么时候扫描回收对象是JVM自己的状态决定的,就算扫描到软引用对象也不一定会回收它,只有内存不够的时候才会回收。
弱引用
弱引用的使用和软引用类似,只是关键字变成了 WeakReference:
MikeChen mikechen = new MikeChen();
WeakReference<MikeChen> wr = new WeakReference<MikeChen>(mikechen );
弱引用的特点是不管内存是否足够,只要发生 GC,都会被回收。
举例说明:
public class WeakHashMapDemo {public static void main(String[] args) throws InterruptedException {myHashMap();myWeakHashMap();}public static void myHashMap() {HashMap<String, String> map = new HashMap<String, String>();String key = new String("k1");String value = "v1";map.put(key, value);System.out.println(map);key = null;System.gc();System.out.println(map);}public static void myWeakHashMap() throws InterruptedException {WeakHashMap<String, String> map = new WeakHashMap<String, String>();//String key = "weak";// 刚开始写成了上边的代码//思考一下,写成上边那样会怎么样? 那可不是引用了String key = new String("weak");String value = "map";map.put(key, value);System.out.println(map);//去掉强引用key = null;System.gc();Thread.sleep(1000);System.out.println(map);}}
弱引用的应用
WeakHashMap
public class WeakHashMapDemo {public static void main(String[] args) throws InterruptedException {myHashMap();myWeakHashMap();}public static void myHashMap() {HashMap<String, String> map = new HashMap<String, String>();String key = new String("k1");String value = "v1";map.put(key, value);System.out.println(map);key = null;System.gc();System.out.println(map);}public static void myWeakHashMap() throws InterruptedException {WeakHashMap<String, String> map = new WeakHashMap<String, String>();//String key = "weak";// 刚开始写成了上边的代码//思考一下,写成上边那样会怎么样? 那可不是引用了String key = new String("weak");String value = "map";map.put(key, value);System.out.println(map);//去掉强引用key = null;System.gc();Thread.sleep(1000);System.out.println(map);}}
当key只有弱引用时,GC发现后会自动清理键和值,作为简单的缓存表解决方案。
ThreadLocal
static class ThreadLocalMap {static class Entry extends WeakReference<ThreadLocal<?>> {Object value;Entry(ThreadLocal<?> k, Object v) {super(k);value = v;}}//......}
ThreadLocal.ThreadLocalMap.Entry 继承了弱引用,key为当前线程实例,和WeakHashMap基本相同。
虚引用
虚引用”顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。
虚引用也称为“幽灵引用”或者“幻影引用”,它是最弱的一种引用关系。
虚引用需要java.lang.ref.PhantomReference 来实现:
A a = new A();
ReferenceQueue<A> rq = new ReferenceQueue<A>();
PhantomReference<A> prA = new PhantomReference<A>(a, rq);
虚引用主要用来跟踪对象被垃圾回收器回收的活动。
虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列 (ReferenceQueue)联合使用,当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之 关联的引用队列中。
Java引用总结
java4种引用的级别由高到低依次为:强引用 > 软引用 > 弱引用 > 虚引用。
以上
Java四大引用详解:强引用、软引用、弱引用、虚引用相关推荐
- java中四种引用类型(对象的强、软、弱和虚引用)
2019独角兽企业重金招聘Python工程师标准>>> 对象的强.软.弱和虚引用在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有 ...
- Java:对象的强、软、弱和虚引用
见:http://zhangjunhd.blog.51cto.com/113473/53092 maven/Java/web/bootstrap/dataTable/app开发QQ群:56686262 ...
- 对象的强、软、弱和虚引用
本文介绍对象的强.软.弱和虚引用的概念.应用及其在UML中的表示. 1.对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有 ...
- 软引用和弱引用的区别_强、软、弱、虚引用的区别和使用
原文阅读: 强.软.弱.虚引用的区别和使用mp.weixin.qq.com Java提供了四种级别的应用类型:强引用.软引用.弱引用及虚引用.那么这四种引用类型有什么区别呢? 首先我们通过一张图来看 ...
- java-基础-强、软、弱、虚引用
Java的四种引用,强弱软虚,用到的场景. JDK1.2之前只有强引用,其他几种引用都是在JDK1.2之后引入的. 强引用(Strong Reference) 最常用的引用类型,如Object obj ...
- jvm系列 (四) ---强、软、弱、虚引用
java引用 目录 jvm系列(一):jvm内存区域与溢出 jvm系列(二):垃圾收集器与内存分配策略 jvm系列(三):锁的优化 我的博客目录 为什么将引用分为不同的强度 因为我们需要实现这样一种情 ...
- JVM 学习(2)—简单理解Java 四大引用(强、软、弱、虚)
一.Java 引用概述 Java 中出现四种引用是为了更加灵活地管理对象的生命周期,以便在不同场景下灵活地处理对象的回收问题.不同类型的引用在垃圾回收时的处理方式不同,可以用来实现不同的垃圾回收策略. ...
- Java对象引用四个级别(强、软、弱、虚)
转载自 Java对象引用四个级别(强.软.弱.虚) 最近,高级Java技术栈微信群中,有一些猿友在讨论JVM中对象的周期问题,有谈到引用的级别,现在为大家做个总结吧,虽然大多数公司并没有意识或者用到这 ...
- 【Java】Java对象引用四个级别(强、软、弱、虚)
文章目录 1.概述 强引用(StrongReference) 软引用(SoftReference) 弱引用(WeakReference) 虚引用(PhantomReference) 2. 扩展阅读 1 ...
- java弱引用弱点_终于有人把Java强、软、弱、虚四种引用知识点整理出来了
强引用就是指在程序代码之中普遍存在的,指创建一个对象并把这个对象赋给一个引用变量,并没有像其它三种引用一样有一个就具体的类来描述.对于强引用对象,即使内存不足,JVM宁愿抛出OutOfMemoryEr ...
最新文章
- 搭建私有Git服务器
- visual c++创建位图资源文件
- 排序算法 —— 冒泡排序
- vb treeview 展开子节点_详解最长公共子序列问题,秒杀三道动态规划题目
- TFS 2010 备份和恢复的完整解决方案
- Python标准库判断图片文件和声音文件的格式
- Linux命令:find命令
- VMware Player 4.0.2 英文官方原版
- 单片机原理及接口技术
- 一文速学-最小二乘法曲线拟合算法详解+项目代码
- win10系统文件拖拽卡顿_如何解决Win10鼠标拖动窗口有延迟?
- 艾媒:ofo用户份额领先摩拜超六成 每10辆共享单车7辆小黄车
- via/route blockage/size blockage/wire/pin guide/pin blockage/partition
- 艺赛旗(RPA)iS-RPA新手课堂 - 这个“鼠标”得会用
- MVCC能保证不产生幻读吗
- 网络编程之编写LSP进行Winsock API监控拦截或LSP注入
- Qt使用三点坐标画圆弧
- BugKu--------你必须让他停下
- 求10000以内质数(以前都是直接打表,现在问到怎么求,瞬间词穷了,还是应该搞懂)
- cad vba 打开文件对话框_AutoCAD VBA选择文件夹的代码