一. 整体架构

Reference: 强引用

SoftReference: 软引用

WeakReference: 弱引用

PhantomReference: 虚引用

二. 强引用

概念

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

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

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

代码示例

myObjct对象创建时默认被强引用指向,GC后不会被回收;后将其置为null,可被回收

    @Testpublic void strongReference() {MyObject myObject = new MyObject();//强引用,未置空无法被GCSystem.out.println("Gc前:" + myObject);System.gc();try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("未置空Gc:" + myObject);myObject = null; //置空可被GCSystem.gc();System.out.println("置空后Gc:" + myObject);}

三. 软引用

概念

软引用是一种相对强引用弱化了一些的引用,需要用java.lang.ref.SoftReference类来实现,可以让对象豁免一些垃圾收集。对于只有软引用的对象来说,当系统内存充足时它不会被回收,当系统内存不足时它会被回收。

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

应用场景

假如有一个应用需要读取大量的本地图片: 如果每次读取图片都从硬盘读取则会严重影响性能, 如果一次性全部加载到内存中又可能造成内存溢出。

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

代码示例

        执行前,设置参数-Xms10m -Xmx10m,保证内存空间不足。

sofeReference对象被设为软引用,当内存空间够用时,GC后不被回收。因空间被设为10m,现创建一个9m的对象导致内存空间不足,此时sofeReference被回收

    @Testpublic void softReference() {SoftReference<MyObject> softReference = new SoftReference<>(new MyObject());//软引用//内存够用System.out.println("Gc前:" + softReference.get());System.gc();try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Gc后内存够用:" + softReference.get());//设置参数-Xms10m -Xmx10m , 内存不够用try {byte[] bytes = new byte[9 * 1024 * 1024];} catch (Exception e) {e.printStackTrace();} finally {System.out.println("Gc后内存不够用:" + softReference.get());}}

四. 弱引用

概念

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

代码示例

        weakReference对象被设为弱引用,一经GC就被回收

    @Testpublic void weakReference() {WeakReference<MyObject> weakReference = new WeakReference<>(new MyObject());//弱引用//内存够用System.out.println("Gc前:" + weakReference.get());System.gc();try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Gc后:" + weakReference.get());}

四. 虚引用

概念

虚引用需要java.lang.ref.PhantomReference类来实现。顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。

如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收,它不能单独使用也不能通过它访问对象,虚引用必须和引用队列 (ReferenceQueue)联合使用。虚引用的主要作用是跟踪对象被垃圾回收的状态。 仅仅是提供了一种确保对象被 finalize以后,做某些事情的机制。PhantomReference的get方法总是返回null,因此无法访问对应的引用对象。

其意义在于:说明一个对象已经进入finalization阶段,可以被gc回收,用来实现比finalization机制更灵活的回收操作。换句话说,设置虚引用关联的唯一目的,就是在这个对象被收集器回收的时候收到一个系统通知或者后续添加进一步的处理。

代码示例

        phantomReference对象被设为虚引用,同样在执行前设置参数-Xms10m -Xmx10m,保证内存空间不足。模拟内存空间不足的情况,使得phantomReference对象被回收,当虚引用对象被回收后会进入ReferenceQueue中

    @Testpublic void phantomReference(){ReferenceQueue<MyObject> referenceQueue = new ReferenceQueue();PhantomReference<MyObject> phantomReference = new PhantomReference<>(new MyObject(),referenceQueue);System.out.println(phantomReference.get());List<byte[]> list = new ArrayList<>();new Thread(() -> {while (true){list.add(new byte[1 * 1024 * 1024]);try { TimeUnit.MILLISECONDS.sleep(600); } catch (InterruptedException e) { e.printStackTrace(); }System.out.println(phantomReference.get());}},"t1").start();new Thread(() -> {while (true){Reference<? extends MyObject> reference = referenceQueue.poll();if (reference != null) {System.out.println("***********有虚对象加入队列了");}}},"t2").start();//暂停几秒钟线程try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); }}

Java强、软、弱、虚四大引用(附代码示例)相关推荐

  1. JVM的四种引用:强,软,弱,虚(与gc有关)

    JVM的四种引用 强 软 弱 虚 强 gc时不回收 软 软引用对象在gc时,在内存溢出前,会回收; 弱 弱引用对象在gc时,不论内存使用情况都会回收; 虚 虚引用对象在gc后,会发送一条通知给 Ref ...

  2. Matlab 制作《最炫民族风》弱爆了,附代码

    Matlab 制作<最炫民族风>弱爆了,附代码 分类: matlab2012-05-22 22:12 1212人阅读 评论(0) 收藏 举报 matlabreference [plain] ...

  3. Spring源码深度解析,Spring源码以及Bean的生命周期(五)(附代码示例:)

    五)Bean 的生命周期,创建---初始化---销毁的过程 目录 五)Bean 的生命周期,创建---初始化---销毁的过程 一 ,  指定初始化方法 init-method 方法​ 二 ,指定销毁 ...

  4. Java 泛型(generics)详解及代码示例、Java 类型通配符详解及代码示例

    Java 泛型(generics)详解及代码示例.Java 类型通配符详解及代码示例 - 概念 Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制 ...

  5. java.util.zip 用法,Java压缩文件工具类ZipUtil使用方法代码示例

    本文实例通过Java的Zip输入输出流实现压缩和解压文件,前一部分代码实现获取文件路径,压缩文件名的更改等,具体如下: package com.utility.zip; import java.io. ...

  6. torch.bernoulli 的使用方法(附代码示例)

    torch.bernoulli 的使用方法(附代码示例) 功能解释 参数 代码示例 功能解释 *torch.bernoulli(input, , generator=None, out=None) → ...

  7. java打印心_使用java打印心型与圆形图案实现代码示例

    本篇文章小编给大家分享一下使用java打印心型与圆形图案实现代码示例,文章代码介绍的很详细,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看. 相信对于打印三角形都没什么难度,只 ...

  8. Android 强软弱虚四大引用★

    1.引用 Java中的引用,类似于C++的指针.通过引用,可以对堆中的对象进行操作.在某个函数中,当创建了一个对象,该对象被分配在堆中,通过这个对象的引用才能对这个对象进行操作. 举例说明: Stri ...

  9. Java 远程控制全实现:高效解决远程控制场景,附代码示例

    JAVA实现远程控制(JAVA in RemoteControl)可以通过Java Remote Method Invocation(Java RMI)或Java Socket编程实现. 1. Jav ...

最新文章

  1. cocos2d-x 2.X for Android中需要使用OpenGL ES 2.0
  2. 用100元买100支笔c语言,用C编程!有100块钱,买100支笔,其中钢笔3元,圆珠笔2元,铅笔0.5元,问各买多少支?...
  3. ERP项目选型实施注意的几点(二)
  4. 关于fckEditor的功能配置-PHP版
  5. python raise语句_python中异常报错的分析处理
  6. BeetleX.WebFamily之ElasticSearch搜索集成
  7. Windows 系统补丁管理策略
  8. java 精灵线程_Java线程的状态分析
  9. [转贴]JAVA:RESTLET开发实例(三)基于spring的REST服务
  10. C#3.0 为我们带来什么(3) —— 初始化器
  11. MyBatis出现红色错误,已解决(Establishing SSL connection without)
  12. vue从哪看组件版本_VUE源码解析之路
  13. Undefined symbols for architecture armv7
  14. 【语音处理】基于matlab GUI语音信号处理与滤波【含Matlab源码 1663期】
  15. Word2007发布文章成功
  16. 轻松搞定技术面系列 1——基础篇
  17. Java Web应用程序开发-深入体验Java Web开发内幕之初步
  18. 使用VAE(变分自动编码器),来预测用户流失.
  19. Unity音频可视化
  20. Windows无法访问网络共享解决办法

热门文章

  1. android 卡顿、ANR优化(1)屏幕刷新机制
  2. Mac使用Aria2下载百度网盘,突破下载限速的方法教程
  3. PAUL:Patch-based Discriminative Feature Learning for Unsupervised Person Re-identification阅读总结
  4. 工控随笔_05_西门子_Step7软件仿真方法
  5. 愿所有程序都有接口,愿所有接口说明都通俗易懂,更新及时
  6. 终结拖延症——行动的理由
  7. 基于CocosCreator的切水果小游戏(二)
  8. jqGrid简单使用、json格式和jsonReader介绍
  9. c++ const 全面总结!
  10. 获取汉字的拼音首字母