一:什么是引用

比如A a = new A();a 就是引用的变量名,它指向一个A对象(引用的值),也就是说,当变量指向一个对象时,这个变量就称为引用变量。引用关系在被创建时,首先要在栈内存(stack)上给引用变量a分配一块内存,而被引用的对象A()存储在堆内存(heap)上,然后由栈上面的引用指向堆中对象的地址。

为什么要定义引用:

  1. 内存使用:定义别名与对象之间的映射关系,以便内存调用,分配

  2. 内存回收:GC回收内存空间时,依据是判断对象的引用与被引用关系

为什么要对引用分类:

  1. 可以让程序员通过代码的方式决定某些对象的生命周期

  2. 有利于GC回收内存空间优化

由此定义了四种引用级别,由高到低依次为:强引用、软引用、弱引用和虚引用


二:实例分析

1)强引用

平时用的最多的引用,类似于 Object obj = new Object(),这种引用的特点是其指向的对象无论如何都不会被 JVM 的垃圾回收器回收;即使是面临着发生内存溢出的风险,只要引用存在,就不会被回收。

public static void main(String[] args) {String name = new String("James");System.out.println("word:" + name);name = new String("Daivd");System.out.println("word:" + name);
}

代码分析:

创建引用name,并指向 James 对象(第2行),然后引用name指向David 对象(第4行),此时,James 对象无外部引用,会在下一次GC中被回收。

2)软引用

如果有一个对象具有软引用。在内存空间足够的情况下,和强引用的生命周期一样,除非内存空间接近临界值,jvm即将抛出oom的时候,垃圾回收器才会将该引用对象进行回收,最大努力避免系统内存溢出的情况。

public class SoftReferenceDemo {public static SoftReference<String> softReference;public static void main(String[] args) {String name = new String("James");softReference = new SoftReference<>(name);System.out.println("word:" + softReference.get());name = new String("Daivd");System.out.println("word:" + softReference.get());System.gc();System.out.println("word:" + softReference.get());ArrayList<String> array = new ArrayList<>();for(int i=0; i<100000000; i++ ) {array.add(String.valueOf(i));}System.gc();System.out.println("word:" + softReference.get());}
}

​​​​​​代码分析:

创建name的强应用,同时指向对象 James(第4行),然后创建softReference的软引用也指向 James(第5行),再次更改name强引用,指向David(第7行),此时,James对象只有softReference软引用存在,由于内存资源不紧张,所以输出值是 James (第10行), 然后模拟内存吃紧情况(第11-14行),此时,经过GC后,softReference的get结果值为null(第16行),也就是说,James 对象被回收了。

3)弱引用

当垃圾回收器扫描到弱引用的对象的时候,不管内存空间是否足够,都会直接被垃圾回收器回收。

public class WeakReferenceDemo {public static WeakReference<String> weakReference;public static void main(String[] args) {String name = new String("James");weakReference = new WeakReference<>(name);    System.out.println("word:" + weakReference.get());name = new String("Daivd");System.out.println("word:" + weakReference.get());System.gc();System.out.println("word:" + weakReference.get());}
}

代码分析:

创建name的强应用,同时指向对象 James(第4行),然后创建weakReference的弱引用也指向 James(第5行),再次更改name强引用,指向David(第7行),此时,James对象只有weakReference软引用存在,然后经过GC后,weakReference的get结果值为null(第10行),也就是说,James 对象被回收了。

4)虚引用

虚引用通过PhantomReference类来实现。无法通过虚引用访问对象的任何属性或函数。仅仅是提供了一种确保对象被 finalize 以后,做某些事情的机制。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。虚引用必须和引用队列 (ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中

三:总结

回顾概述本文传达的知识点

引用类型 GC回收触发点 生命周期 场景应用
强引用 不回收 JVM停止运行后终止 正常应用
软引用 内存不足 内存不足时终止 从远程获取到的资源文件,通过软应用缓存下来,用来实现类缓存机制
弱引用 GC周期内 GC运行后终止 使用弱引用避免内存泄露
虚引用 未知 未知 跟踪对象被垃圾回收器回收的活动,当一个虚引用关联的对象被垃圾收集器回收之前会收到一条系统通知

更多信息请关注 微信公众号 :  白白家族
    或扫描白白家族公众号二维码:

Java引用界的四大天王相关推荐

  1. 号称BI商业智能界的“四大天王”

    基于云部署的现代商业智能与数据分析平台(国内似乎只有应用上云,数据本地化的趋势)正在逐步占据主流市场.随着市场在易用性和增强分析(augmented analytics)的变革,数据与分析领导者正在逐 ...

  2. 多线程与高并发 笔记,非面向初学者 二:java引用,高并发多线程容器,线程池

    网页右边,向下滑有目录索引,可以根据标题跳转到你想看的内容 如果右边没有就找找左边 上一节:JUC锁,一些面试题和源码讲解 1.引用 java引用共4种,强软弱虚 强引用:我们普通的new一个对象,就 ...

  3. java回收类_Java的内存回收——Java引用的种类

    1.Java引用的种类 Java是面向对象的编程语言,一个Java程序往往需要创建大量的Java类,然后对各Java类创建大量的Java对象,再调用这些Java对象的属性和方法来操作它们. 程序员需要 ...

  4. java弱引用怎么手动释放,十分钟理解Java中的弱引用,十分钟java引用

    十分钟理解Java中的弱引用,十分钟java引用 本篇文章尝试从What.Why.How这三个角度来探索Java中的弱引用,帮助大家理解Java中弱引用的定义.基本使用场景和使用方法.由于个人水平有限 ...

  5. java引用 弱引用_了解Java弱引用

    java引用 弱引用 我最近没来得及关注这个博客,最重要的是,我没有为与技术界的所有人保持联系而致歉. 最近,我偶然发现了自Java 1.2起可用的java.lang.ref软件包,但具有讽刺意味的是 ...

  6. 中国第一批写java的人_中国java开源界最可爱的人们

    评论 # re: 中国java开源界最可爱的人们 2007-12-07 15:29 sitinspring 如果少一些抒情,多一点实质内容,文章更耐看.  回复  更多评论 # re: 中国java开 ...

  7. 深切悼念JAVA培训界第一人张孝祥老师意外辞世

    2011年12月31日晚,张孝祥老师突然发生意外不幸离世,初步判断可能是平时操劳过度,身体状况本来不是很好加上突然剧烈运动导致的意外,刚听到这个消息的时候,无法相信,甚至难以接受,张老师在我的心目一直 ...

  8. Java引用和C++引用

    Java引用和C++引用区别: public class Tester{ public static void main(String[] args){Integer var1=new Integer ...

  9. 4种Java引用浅解

    最近研究Java Cache实现,发现使用到了软引用(SoftReference),不太理解,查阅了JDK文档.代码以及几篇文章.做个小结,如有错误,欢迎指正. 之所以想学习一下Java的几种引用类型 ...

最新文章

  1. python大家都会吗_一篇告诉你为什么人人都应该学点Python?
  2. 迟到两年,Lu1与Cee合作的经典单曲《自己做决定》终于发布MV了!
  3. Android 从一个Activity跳转到另一个Activity获取第二个Activity的返回值
  4. 使用 C++的第三方库 jsoncpp的步骤以及出现的问题
  5. 面试必备的分布式事物方案
  6. 【Marva Collins' Way】第三章
  7. python安装第三方库时报错 SyntaxError: invalid syntax
  8. 路由器性能测试工具_小米路由器AX3600与AX1800 MESH 实测
  9. python怎么编写流氓软件_PBot很多程序员都知道吧?深度分析一款基于python的恶意软件!...
  10. 2、启动Spring Boot 容器
  11. Flutter 即将占领整个 Web 开发
  12. c# Invalidate() Update() Refresh()的区别
  13. Windows系统下载Android源码
  14. Java 汉字转拼音(完美支持解决多音字)
  15. RISC-V嵌入式开发入门篇2:RISC-V汇编语言程序设计(上)
  16. 《东周列国志》第四十四回 叔詹据鼎抗晋侯 弦高假命犒秦军
  17. ConcurrentHashMap插入与遍历时出现混乱
  18. HTML+css+js实现网页时钟、全网做得最好的时钟!
  19. 《操作系统》工作集详解
  20. matlab处理时间数据绘图

热门文章

  1. mysql利用存储过程批量插入一千万数据(半小时)
  2. 多模态学习(Multimodal Deep Learning)研究进展综述(转载)
  3. 卖家被骗上万元,已报警立案-跨境知道
  4. 如何将ubuntu配置为路由器
  5. C#中 out 参数的使用
  6. 互联网行测笔试题之最头疼的找规律
  7. python熊猫弹幕_Pandas+Matplotlib:视频弹幕统计分析
  8. 数商云跨境电商平台运营总结:整合渠道+深引流量
  9. java弹框刷新原页面_JavaScript:关闭弹出窗口时刷新父窗口
  10. 八防区模块接线图_消防模块接线方法和接线图【借鉴实操】