JVM之强引用、软引用、弱引用、虚引用


  1. 整体架构
  2. 强引用Reference
  3. 软引用SoftReference
  4. 弱引用WeakReference
  5. 软引用和弱引用的适用场景
  6. WeakHashMap案例演示和解析
  7. ReferenceQueue引用队列介绍
  8. 虚引用PhantomReference

1. 整体架构



2. 强引用Reference


  1. 当内存不足,JVM开始垃圾回收,对于强引用的对象,就算是出现了00M也不会对该对象进行回收,死都不收。

  2. 强引用是我们最常见的普通对象引用,只要还有强引用指向一个对象,就能表明对象还“活着”,垃圾收集器不会碰这种对象。在Java中最常见的就是强引用,把一个对象赋给一个引用变量,这个引用变量就是一个强引用。当一个对象被强引用变量引用时,它处于可达状态,它是不可能被垃圾回收机制回收的,即使该对象以后永远都不会被用到JVM也不会回收。因此强引用是造成Java内存泄漏的主要原因之一

  3. 对于一个普通的对象,如果没有其他的引用关系,只要超过了引用的作用域或者显式地将相应(强)引用赋值为null,一般认为就是可以被垃圾收集的了〈当然具体回收时机还是要看垃圾收集策略)。

  4. 图解:


3. 软引用SoftReference


  1. 软引用是一种相对强引用弱化了一些的引用,需要用java.lang.ref.SoftReference类来实现,可以让对象豁免一些

  2. 对于只有软引用的对象来说,当系统内存充足时它不会被回收,当系统内存不足时它会被回收

  3. 软引用通常用在对内存敏感的程序中,比如高速缓存就有用到软引用,内存够用的时候就保留,不够用就回收!

  4. 示例:当内存充足时:

  5. 示例:当内存不足时


4. 弱引用WeakReference


  1. 弱引用需要用Java.lang.ref.WeakReference类来实现,它比软引用的生存期更短,对于只有弱引用的对象来说,只要垃圾回收机制一运行,不管JVM的内存空间是否是够,都会回收该对象占用的内存。

2.代码示例:

public class WeakReferenceDemo {public static void main(String[] args) {Object o1 = new Object();WeakReference<Object> weakReference = new WeakReference<>(o1);System.out.println(o1);System.out.println(weakReference.get());o1 = null;System.gc();System.out.println("==============");System.out.println(o1);System.out.println(weakReference.get());}
}
  1. 执行结果

5. 软引用和弱引用的适用场景


  1. 假如有一个应用需要读取大量的本地图片:

    1. 如果每次读取图片都从硬盘读取则会严重影响性能,
    2. 如果一次性全部加载到内存中又可能造成内存溢出。
  2. 此时使用软引用可以解决这个问题。

    1. 设计思路是:用一个HashMap来保存图片的路径和相应图片对象关联的软引用之间的映射关系,在内存不足时,JVM会自动回收这些缓存图片对象所占用的空间,从而有效地避免了00M的问题。
  3. Map<String,SoftReference>imageCache=new HashMap<String,SoftReference>();


6. WeakHashMap案例演示和解析


  1. 面试问上面的部分就很引出WeakHashMap,所以来说一说。

  2. 概述:


    即当WeakHashMap的key为null,它也会被垃圾回收。

  3. 代码示例:

import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.WeakHashMap;public class WeakReferenceDemo {public static void main(String[] args) {myHashMap();System.out.println("==========");myWeakHashMap();}private static void myWeakHashMap() {WeakHashMap<Integer,String> map = new WeakHashMap<>();Integer key = new Integer(2);String value = "WeakHashMap";map.put(key,value);System.out.println(map);key = null;System.out.println(map);System.gc();System.out.println(map);}private static void myHashMap() {HashMap<Integer,String> map = new HashMap<>();Integer key = new Integer(1);String value = "HashMap";map.put(key,value);System.out.println(map);key = null;System.out.println(map);System.gc();System.out.println(map);}
  1. 执行结果:

7. ReferenceQueue引用队列介绍


  1. java提供了4种引用类型,在垃圾回收的时候,都有自己各自的特点。
  2. ReferenceQueue是用来配合引用工作的,没有Referencequeue一样可以运行
  3. 创建引用的时候可以指定关联的队列,当GC释放对象内存的时候,会将引用加入到引用队列,如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动,这相当于一种通知机制。

4.当关联的引用队列中有数据的时候,意味着引用指向的堆内存中的对象被回收。通过这种方式,JVM运行我们在对象被销毁后,做一些我们自己想做的事情。

  1. 代码测试:
public class ReferenceQueueDemo {public static void main(String[] args) throws InterruptedException {Object o1 = new Object();ReferenceQueue<Object> referenceQueue = new ReferenceQueue();WeakReference<Object> weakReference = new WeakReference<>(o1,referenceQueue);System.out.println(o1);System.out.println(weakReference.get());System.out.println(referenceQueue.poll());System.out.println("=====================");o1 = null;System.gc();Thread.sleep(500);System.out.println(o1);System.out.println(weakReference.get());System.out.println(referenceQueue.poll());}
}
  1. 执行结果

8. 虚引用PhantomReference


  1. 虚引用需要java.lang.ref.PhantomReference类来实现。

  2. 顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收,它不能单独使用也不能通过它访问
    对象,虚引用必须和引用队列(ReferenceQueue)联合使用。

  3. 虚引用的主要作用是跟踪对象被垃圾回收的状态。仅仅是提供了一种确保对象被finalize以后,做某些事情的机制。PhantomReference的get方法总是返回null,因此无法访问对应的引用对象。其意义在于说明一个对象己经进入俑finalization阶段,可以被gc回收,用来实现比finalization机制更灵活的回收操作。

  4. 换句话说,设置虚引用关联的唯一目的,就是在这个对象被收集器回收的时候收到一个系统通知或者后续添加进一步的处理。Java技术允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。

  5. 代码示例:

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;public class PhantomReferenceDemo {public static void main(String[] args) throws InterruptedException {Object o1 = new Object();ReferenceQueue<Object> referenceQueue = new ReferenceQueue();PhantomReference<Object> phantomReference = new PhantomReference<>(o1,referenceQueue);System.out.println(o1);System.out.println(phantomReference.get());System.out.println(referenceQueue.poll());System.out.println("=====================");o1 = null;System.gc();Thread.sleep(500);System.out.println(o1);System.out.println(phantomReference.get());System.out.println(referenceQueue.poll());}
}
  1. 执行结果:

JVM之强引用、软引用、弱引用、虚引用相关推荐

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  8. Java的四大引用强、软、弱、虚

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

  9. Java四大引用(强、软、弱、虚)

    目录 强引用 软引用 弱引用 虚引用 强引用 也是我们平时用得最多的, new 一个对象就是强引用,例如 Object obj = new Object(); 当JVM的内存空间不足时,宁愿抛出Out ...

  10. Java 的四大引用(强、软、弱、虚)

    在 jdk1.2 以后,Java 对于引用的概念进行了扩充,将引用分为强引用(Strong Reference).软引用(Soft Reference).弱引用(Weak Reference).虚引用 ...

最新文章

  1. 求圆和椭圆上任意角度的点的坐标
  2. php使用accdb,php如何连接access2007的accdb格式数据库文件?
  3. linux启动管理,Linux启动管理 详述
  4. Caret模型训练和调参更多参数解读(2)
  5. 为什么我不推荐你盲目追求微服务?迟早要吃亏!
  6. 一位读者关于买房的困惑
  7. Waymo已经开始绘制亚特兰大地图数据,自动驾驶汽车路测地点又添新城
  8. 水经注全球离线地图数据3.0即将发布
  9. 小米商城html+css+js全代码
  10. java识别验证码图片_Java识别图像、验证码
  11. 9012 递归求n的阶乘
  12. 正则中圆括号()方括号[]大括号{}的区别和用法
  13. 中秋节的特别礼物----属于程序员的专有浪漫
  14. 交叉编译apr和apr-util库
  15. JS生成浏览器唯一标识解决方案
  16. 咸鱼半学期总结+老年人康复训练
  17. Javascript 与 或 非 符号
  18. C语言编译出现give arg types警告问题
  19. Intellij IDEA——启动Tomcat控制台输出繁体乱码
  20. Python中求最大值和最小值max()函数、min()函数

热门文章

  1. 惠普大佬:未来30年四大趋势将推动科技产业发展
  2. vue2.0 组件通信
  3. linux硬件时间修改与查看
  4. vsftpd虚拟用户和本地用户不能共存的解决方法
  5. Unknown opcode
  6. UltraWebGrid控件在开发ASP.NET项目中的使用方法和技巧(转)
  7. sql 2005分区表
  8. CodeForces - 467C George and Job(二维dp)
  9. CodeForces - 850C Arpa and a game with Mojtaba(博弈+sg函数)
  10. java比较两个对象重写,不重写equals进行两个对象间的深度比较