人物背景

老徐,男,本名徐福贵,从事Java相关研发工作多年,职场老油条,摸鱼小能手,虽然岁数不大但长的比较着急,人称老徐。据说之前炒某币败光了所有家产,甚至现在还有欠债。

阿珍,女,本名陈家珍,刚刚入职不久的实习生,虽然是职场菜鸟但聪明好学。据说是学校的四大校花之一,追求她的人从旺角排到了铜锣湾,不过至今还单身。

阿珍:“老徐,你这茶杯了泡的什么?红红的。”
老徐:“这是枸杞呀。”
阿珍:“枸杞?你最近什么干多了,这么!”
老徐:“怎么可能?看我这身体,不的好吧!”
阿珍一脸坏笑地说:“那就是了。”
老徐的老脸一红,辩解到:“我这是养养生,我很的,好吧。”
看着老徐的窘态,阿珍笑出来声。老徐起身刚要走,阿珍一把拽住老徐,说:“跟你开玩笑呢,问你个正事,我一直分不清Java的强引用、软引用、弱引用、虚引用,给我讲讲呗。”
老徐立刻自信满满的坐下,说:“那你可问对人了,我对这方面颇有研究。这四种引用级别由高到低依次是:强引用、软引用、弱引用、虚引用。”

强引用(StrongReference)

强引用是Java中最常见的引用方式,99.99%用的都是强引用。我们创建了一个对象,并把它赋值给某一个变量,我们就可以通过这个变量操作实际的对象了,比如:

String name = "万猫学社";
System.out.println(name);

当一个对象被一个或者多个变量强引用时,它就是处于一个可达状态,不会被垃圾回收机制回收掉。即使在内存不够的情况下,Java虚拟机宁愿抛出OutOfMemoryError异常,也不会回收这样的对象。

软引用(SoftReference)

软引用是通过SoftReference类进行实现的,当一个对象只有软引用的时候,Java虚拟机的垃圾回收机制运行后,当内存空间足够时,它就不会被回收掉;当内存空间不够时,它就会被回收掉。比如:

SoftReference<byte[]> softReference = new SoftReference<>(new byte[1024 * 1024 * 5]);
System.out.println("垃圾回收前:" + softReference.get());//建议Java虚拟机执行垃圾回收
System.gc();System.out.println("内存足够时,垃圾回收后:" + softReference.get());byte[][] bytes = new byte[10][];
for (int i = 0; i < 10; i++) {bytes[i] = new byte[1024 * 1024 * 1];
}System.out.println("内存不足时,垃圾回收后:" + softReference.get());

在运行时加入-Xmx15M (设置Java堆的最大内存为15M)和-XX:+PrintGC(开启垃圾回收的日志打印)参数,我们就可以看到下面的结果:

垃圾回收前:[B@1de0aca6
[GC (System.gc())  9173K->6495K(15872K), 0.0033951 secs]
[Full GC (System.gc())  6495K->6434K(15872K), 0.0149312 secs]
内存足够时,垃圾回收后:[B@1de0aca6
[GC (Allocation Failure)  9588K->9570K(15872K), 0.0013485 secs]
[Full GC (Ergonomics)  9570K->9506K(15872K), 0.0032467 secs]
[Full GC (Ergonomics)  12659K->12549K(15872K), 0.0083257 secs]
[Full GC (Ergonomics)  13573K->13573K(15872K), 0.0043525 secs]
[Full GC (Allocation Failure)  13573K->8435K(15872K), 0.0065695 secs]
内存不足时,垃圾回收后:null

可以看到,当内存空间足够时,软引用的对象不会被回收掉;当内存空间不够时,软引用的对象就会被回收掉。

弱引用(WeakReference)

弱引用是通过WeakReference类进行实现的,弱引用和软引用很类似,但是比软引用的级别更低。当一个对象只有弱引用的时候,Java虚拟机的垃圾回收机制运行后,无论内存是否足够,它都会被回收掉。比如:

WeakReference<byte[]> weakReference = new WeakReference<>(new byte[1024 * 1024 * 5]);
System.out.println("垃圾回收前:" + weakReference.get());//建议Java虚拟机执行垃圾回收
System.gc();System.out.println("内存足够时,垃圾回收后:" + weakReference.get());

同样的,在运行时加入-Xmx15M (设置Java堆的最大内存为15M)和-XX:+PrintGC(开启垃圾回收的日志打印)参数,我们就可以看到下面的结果:

垃圾回收前:[B@1de0aca6
[GC (System.gc())  9150K->6481K(15872K), 0.0015689 secs]
[Full GC (System.gc())  6481K->1317K(15872K), 0.0062846 secs]
内存足够时,垃圾回收后:null

可以看到,即使在内存足够的时候,弱引用的对象也会被回收掉。

虚引用(PhantomReference)

虚引用通过PhantomReference类进行实现的,虚引用完全类似于没有引用。如果一个对象只有一个虚引用,那么它就是和没有引用差不多。虚引用主要用于跟踪对象被垃圾回收的状态,虚引用不能单独使用,必须和引用队列(ReferenceQueue)一起使用。我们不能通过虚引用获取到被引用的对象,只有在该对象被回收后,该对象的虚引用会被放到和虚引用关联的引用队列中,比如:

ReferenceQueue referenceQueue = new ReferenceQueue();
PhantomReference<byte[]> phantomReference = new PhantomReference<>(new byte[1024 * 1024 * 5], referenceQueue);System.out.println("垃圾回收前:" + phantomReference.get());byte[][] bytes = new byte[10][];
for (int i = 0; i < 5; i++) {bytes[i] = new byte[1024 * 1024 * 1];
}System.out.println("垃圾回收后:" + referenceQueue.poll());

同样的,在运行时加入-Xmx15M (设置Java堆的最大内存为15M)和-XX:+PrintGC(开启垃圾回收的日志打印)参数,我们就可以看到下面的结果:

垃圾回收前:null
[GC (Allocation Failure)  9068K->6517K(15872K), 0.0019272 secs]
[GC (Allocation Failure)  9713K->9621K(15872K), 0.0015966 secs]
[Full GC (Ergonomics)  9621K->9506K(15872K), 0.0092758 secs]
垃圾回收后:java.lang.ref.PhantomReference@1de0aca6

可以看到,不能通过虚引用获取到被引用的对象,在该对象被回收后,可以从引用队列中获取对应的虚引用。

老徐看着阿珍一脸懵逼的样子说:“小朋友,你是不是有很多问号?”“信息量有点大,我得慢慢消化消化。”阿珍回答到。老徐说:“没关系,我给你简单总结一下,很方便理解和记忆。”

总结

  • 强引用:Java中最常见的引用方式,即使内存不足也不会被垃圾回收。
  • 软引用:当内存不足时,垃圾回收机制运行后对象被回收。
  • 弱引用:无论内存是否足够,垃圾回收机制运行后对象被回收。
  • 虚引用:主要用于跟踪对象被垃圾回收的状态,必须和引用队列一起使用。

最后,谢谢你这么帅,还给我点赞关注

老徐和阿珍的故事:强引用、软引用、弱引用、虚引用,傻傻分不清楚相关推荐

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

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

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

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

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

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

  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的四大引用强、软、弱、虚

    一.什么是引用 首先要明白什么是一个引用呢?Object o = new Object()这就是一个引用了,一个变量指向new出来的对象,这个变量就叫一个引用,引用这个东西,在java里面分4种,普通 ...

最新文章

  1. Exception loading sessions from persistent storage
  2. LeetCode Single Number II(位操作)
  3. UVA11100旅行(大包装小包,问最少多少个包)
  4. 一个跨国银行的敏捷转型案例要点之全员培训
  5. 通过excel模板文件根据数据库数据修改其中的单元格数据
  6. CommandLineRunner与ApplicationRunner接口的使用及源码解析
  7. Ext.form.field.CheckBox复选框和Ext.form.field.Radio单选框
  8. C语言keywordstatic的绝妙用途
  9. 古谚、评论与论断、名篇与名言
  10. [codeVS1917] 深海机器人问题(费用流,拆边)
  11. Atitit.信息论原理概论attilax总结
  12. mysql blob 字段,mysql BLOB字段类型用法介绍
  13. 打开360浏览器显示无法连接服务器错误,最近360浏览器老是无法打开网页,提示错误如图,但是只要刷新就可以打开了,这是怎么回事?...
  14. minecraft兑换码领取!
  15. [Git命令]上传单个文件到GitHub项目已有文件夹
  16. 常见的请求错误HTTP状态码
  17. 遥遥领先影像组件:dicomobjects.ocx
  18. java中包地作用_什么是PCB设计中的包地
  19. Python学习关键tip记录
  20. 手把手教你win10下安装Anaconda

热门文章

  1. QQ拼音输入法使用评价
  2. 仿Windows画板喷漆笔刷效果
  3. 数仓工具—Hive的数据组织管理方式(4)
  4. MyEclipse更换背景豆沙绿
  5. ppt流程图箭头分叉_PPT实用模版大全(最全箭头、流程图).ppt
  6. java 拟合曲线_关于java实现自定义曲线拟合的研究
  7. [Linux]_ELVE_ssh登录远程阿里服务器
  8. [笔记]_ELVE_正则表达式
  9. 知识图谱-知识体系与知识融合-实体消歧
  10. 华为充电协议_华为推出超级快充多协议充电器,支持65W USB PD快充输出