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四大引用详解:强引用、软引用、弱引用、虚引用相关推荐

  1. java中四种引用类型(对象的强、软、弱和虚引用)

    2019独角兽企业重金招聘Python工程师标准>>> 对象的强.软.弱和虚引用在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有 ...

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

    见:http://zhangjunhd.blog.51cto.com/113473/53092 maven/Java/web/bootstrap/dataTable/app开发QQ群:56686262 ...

  3. 对象的强、软、弱和虚引用

    本文介绍对象的强.软.弱和虚引用的概念.应用及其在UML中的表示. 1.对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有 ...

  4. 软引用和弱引用的区别_强、软、弱、虚引用的区别和使用

    原文阅读: 强.软.弱.虚引用的区别和使用​mp.weixin.qq.com Java提供了四种级别的应用类型:强引用.软引用.弱引用及虚引用.那么这四种引用类型有什么区别呢? 首先我们通过一张图来看 ...

  5. java-基础-强、软、弱、虚引用

    Java的四种引用,强弱软虚,用到的场景. JDK1.2之前只有强引用,其他几种引用都是在JDK1.2之后引入的. 强引用(Strong Reference) 最常用的引用类型,如Object obj ...

  6. jvm系列 (四) ---强、软、弱、虚引用

    java引用 目录 jvm系列(一):jvm内存区域与溢出 jvm系列(二):垃圾收集器与内存分配策略 jvm系列(三):锁的优化 我的博客目录 为什么将引用分为不同的强度 因为我们需要实现这样一种情 ...

  7. JVM 学习(2)—简单理解Java 四大引用(强、软、弱、虚)

    一.Java 引用概述 Java 中出现四种引用是为了更加灵活地管理对象的生命周期,以便在不同场景下灵活地处理对象的回收问题.不同类型的引用在垃圾回收时的处理方式不同,可以用来实现不同的垃圾回收策略. ...

  8. Java对象引用四个级别(强、软、弱、虚)

    转载自 Java对象引用四个级别(强.软.弱.虚) 最近,高级Java技术栈微信群中,有一些猿友在讨论JVM中对象的周期问题,有谈到引用的级别,现在为大家做个总结吧,虽然大多数公司并没有意识或者用到这 ...

  9. 【Java】Java对象引用四个级别(强、软、弱、虚)

    文章目录 1.概述 强引用(StrongReference) 软引用(SoftReference) 弱引用(WeakReference) 虚引用(PhantomReference) 2. 扩展阅读 1 ...

  10. java弱引用弱点_终于有人把Java强、软、弱、虚四种引用知识点整理出来了

    强引用就是指在程序代码之中普遍存在的,指创建一个对象并把这个对象赋给一个引用变量,并没有像其它三种引用一样有一个就具体的类来描述.对于强引用对象,即使内存不足,JVM宁愿抛出OutOfMemoryEr ...

最新文章

  1. 搭建私有Git服务器
  2. visual c++创建位图资源文件
  3. 排序算法 —— 冒泡排序
  4. vb treeview 展开子节点_详解最长公共子序列问题,秒杀三道动态规划题目
  5. TFS 2010 备份和恢复的完整解决方案
  6. Python标准库判断图片文件和声音文件的格式
  7. Linux命令:find命令
  8. VMware Player 4.0.2 英文官方原版
  9. 单片机原理及接口技术
  10. 一文速学-最小二乘法曲线拟合算法详解+项目代码
  11. win10系统文件拖拽卡顿_如何解决Win10鼠标拖动窗口有延迟?
  12. 艾媒:ofo用户份额领先摩拜超六成 每10辆共享单车7辆小黄车
  13. via/route blockage/size blockage/wire/pin guide/pin blockage/partition
  14. 艺赛旗(RPA)iS-RPA新手课堂 - 这个“鼠标”得会用
  15. MVCC能保证不产生幻读吗
  16. 网络编程之编写LSP进行Winsock API监控拦截或LSP注入
  17. Qt使用三点坐标画圆弧
  18. BugKu--------你必须让他停下
  19. 求10000以内质数(以前都是直接打表,现在问到怎么求,瞬间词穷了,还是应该搞懂)
  20. cad vba 打开文件对话框_AutoCAD VBA选择文件夹的代码

热门文章

  1. Windows To Go屏蔽本机硬盘教程
  2. W7启动报错0xc0000f
  3. Html DOM元素的childNodes和children的区别
  4. 整理一批正在学、正在看、正在用,前端工具
  5. 【10年运维整理】服务器常见故障及其解决方法
  6. Android第一行代码第二版简要总结
  7. 复现Detectron2-blendmask之冰墩墩雪容融自定义数据集语义分割
  8. 文语通5.0破解版安装说明
  9. 【Java】java日历
  10. 转自阿里巴巴的开发手册