转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52637333

背景:收到公众投稿,《从面试题中看Java的Reference(引用)》,分析的很不错,总感觉少了实际的例子和应用场景。于是结合自己工作中场景,小总结一下。看下Agenda如下:

  • 强引用
  • 软引用
  • 弱引用
  • 什么时候使用软引用,什么时候使用弱引用?
  • 虚引用

一、强引用

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

假设以上代码是在方法内运行的,那么局部变量str将被分配在栈空间上,而对象StringBuffer实例,被分配在堆空间中。局部变量str指向StringBuffer实例所在的堆空间,通过str可以操作该实例,那么str就是StringBuffer的引用。

此时,运行一个赋值语句:

那么,str所指向的对象也将被str1所指向,同时在局部栈空间上会分配空间存放str1变量。此时,该StringBuffer实例就有两个引用。对引用的”==”操作用于表示两个操作数所指向的堆空间地址是否相同,不表示两个操作数所指向的对象是否相等。

强引用特点:

  • 强引用可以直接访问目标对象。
  • 强引用所指向的对象在任何时候都不会被系统回收。JVM宁愿抛出OOM异常,也不会回收强引用所指向的对象。
  • 强引用可能导致内存泄露。

二、软引用

软引用是除了强引用外,最强的引用类型。可以通过java.lang.ref.SoftReference使用软引用。一个持有软引用的对象,不会被JVM很快回收,JVM会根据当前堆的使用情况来判断何时回收。当堆的使用率临近阈值时,才会回收软引用的对象。

看下我工作中使用到软引用的场景,加载一个1080x1920分辨率的图,约900多K, 对于我们来说,这个图已是非常大了。

  • 首先通过BitmapFactory.decodeStream构造一个大图bitmap
  • 然后把这个bitmap转成Drawble类型,构成强引用。
  • 接着使用SoftReference构造这个drawable对象的软引用drawables.
  • 最后通过软引用的get()方法,取得drawable对象实例的强引用,发现对象被未回收。在GC在内存充足的情况下,不会回收软引用对象。

  • 在实际中,一起请求很多相关图片,从网络,这时就会请求非常多的内存空间,导致内存吃紧,系统开始会GC。这次GC后,drawables.get()不再返回Drawable对象,而是返回null,这时屏幕上背景图不显示,说明在系统内存紧张的情况下,软引用被回收。

  • 使用软引用以后,在OutOfMemory异常发生之前,这些缓存的图片资源的内存空间可以被释放掉的,从而避免内存达到上限,避免Crash发生。

  • 需要注意的是,在垃圾回收器对这个Java对象回收前,SoftReference类所提供的get方法会返回Java对象的强引用,一旦垃圾线程回收该Java对象之后,get方法将返回null。所以在获取软引用对象的代码中,一定要判断是否为null,以免出现NullPointerException异常导致应用崩溃。

到底什么时候使用软引用,什么时候使用弱引用呢?

个人认为,如果只是想避免OutOfMemory异常的发生,则可以使用软引用。如果对于应用的性能更在意,想尽快回收一些占用内存比较大的对象,则可以使用弱引用。

还有就是可以根据对象是否经常使用来判断。如果该对象可能会经常使用的,就尽量用软引用。如果该对象不被使用的可能性更大些,就可以用弱引用。

另外,和弱引用功能类似的是WeakHashMap。WeakHashMap对于一个给定的key,其映射的存在并不阻止垃圾回收器对该键的回收,回收以后,其条目从映射中有效地移除。WeakHashMap使用ReferenceQueue实现的这种机制。

三、 弱引用

弱引用是一种比软引用较弱的引用类型。在系统GC时,只要发现弱引用,不管系统堆空间是否足够,都会将对象进行回收。但是,由于垃圾回收器的线程通常优先级很低,因此,并一不定能很快的发现持有弱引用的对象。这种情况下,弱引用对象可以存在较长的一段时间。一旦一个弱引用对象被垃圾回收器回收,便会加入到一个注册引用队列中。

看一个工作中实例:播放器的播放Panel,是一个View,就是在视频播放时,可以show、hide, 也可以拖拽进度条之类,还有上面的音量,亮度调节等。这样一个view,我们用弱引用,因为在视频播放过程中,不论硬解还是软解,都将占用大量内存。保证视频的渲染效果。

在VideoControllerView.java 有如下一段代码:

在GC之前,弱引用对象并未被垃圾回收器发现,因此通过mView.get()方法可以取得对应的强引用。但是只要进行垃圾回收,弱引用对象一旦被发现,便会立即被回收,并加入注册引用队列中。此时,再次通过mView.get()方法取得强引用就会失败。

注意:软引用,弱引用都非常适合来保存那些可有可无的缓存数据。如果这样做,当系统内存不足时,这些缓存数据会被回收,不会导致内存溢出。而当内存资源充足时,这些缓存数据又可以存在相当长的时间。

四、 虚引用

  • 虚引用是所有引用类型中最弱的一个。一个持有虚引用的对象,和没有引用几乎是一样的,随时都可能被垃圾回收器回收。当试图通过虚引用的get()方法取得强引用时,总是会失败。并且,虚引用必须和引用队列一起使用,它的作用在于跟踪垃圾回收过程。
  • 当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在垃圾回收后,销毁这个对象,奖这个虚引用加入引用队列。
  • 实际中几乎没用,暂不介绍。

最后一张图总结下:

第一时间获得博客更新提醒,以及更多android干货,源码分析,欢迎关注我的微信公众号,扫一扫下方二维码或者长按识别二维码,即可关注。

如果你觉得好,随手点赞,也是对笔者的肯定,也可以分享此公众号给你更多的人,原创不易

Android性能提升之强引用、软引用、弱引用、虚引用使用的更多相关文章

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

    转自: http://zhangjunhd.blog.51cto.com/113473/53092 1.对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无 ...

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

    1.对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有对象处于可触及(reachable)状态,程序才能使用它.从JDK ...

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

    1.对象的强.软.弱和虚引用 转自:http://zhangjunhd.blog.51cto.com/113473/53092/ 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无 ...

  4. java基础知识再学习--集合框架-对象的强、软、弱和虚引用

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://zhangjunhd.blog.51cto.com/113473/53092 本文 ...

  5. Java对象的强、软、弱和虚引用原理+结合ReferenceQueue对象构造Java对象的高速缓存器

    //转 http://blog.csdn.net/lyfi01/article/details/6415726 1.Java对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变 ...

  6. Java:对象的强、软、弱和虚引用[转]

    原文链接:http://zhangjunhd.blog.51cto.com/113473/53092/ 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法 ...

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

    对象的强.软.弱和虚引用在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有对象处于可触及(reachable)状态,程序才能使用它.从JDK 1.2 ...

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

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

  9. 0030 Java学习笔记-面向对象-垃圾回收、(强、软、弱、虚)引用

    垃圾回收特点 垃圾:程序运行过程中,会为对象.数组等分配内存,运行过程中或结束后,这些对象可能就没用了,没有变量再指向它们,这时候,它们就成了垃圾,等着垃圾回收程序的回收再利用 Java的垃圾回收机制 ...

  10. Java中四种引用:强、软、弱、虚引用

    这篇文章非常棒:http://alinazh.blog.51cto.com/5459270/1276173 Java中四种引用:强.软.弱.虚引用 1.1.强引用当我们使用new 这个关键字创建对象时 ...

随机推荐

  1. 处处留心皆学问——由“display:inline-block;”导致的间距引发的思考。

    昨天在做一个demo时遇到了一个问题:我有五个li需要并排排列,然后自然而然的我给它们设了display:inline-block;但是,过了很久之后发现,除了我写的样式外,它默认有一个间距,我们都不 ...

  2. java利用poi来读取execl表格返回对象

    利用poi来读取execl表格,返回一个对象(可能有点不完善,但是应该能满足平常的所用),用到了反射等等; 使用的jar包有: commons-collections4-4.1.jar poi-3.1 ...

  3. PHPCMS v9.6.0 wap模块 SQL注入

    调试这个漏洞的时候踩了个坑,影响的版本是php5.4以后. 由于漏洞是由parse_str()函数引起的,但是这个函数在gpc开启的时候(也就是php5.4以下)会对单引号进行过滤\'  . 看这里: ...

  4. tmux 终端复用详解

    tmux是什么 我们在linux服务器上的工作一般都是通过一个远程的终端连接软件连接到远端系统进行操作,例如使用xshell或者SecureCRT工具通过ssh进行远程连接.在使用过程中,如果要做比较 ...

  5. [WC 2011]Xor

    Description Input 第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目. 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 ...

  6. 【NOIP2017 OFO】

    ·奇怪的标题可能预示着这一篇博文不是讲算法或者分享题目的吧. [一只情绪化的兔子]      今年的11月12日出奇地比去年温暖.两场比赛结束后的我们在临走前去尝试了OFO共享单车,在成都电子科技大学 ...

  7. hdu 5573Binary Tree

    Binary Tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Tota ...

  8. WPF 实现换肤功能

    将所有控件的基本样式汇集到一个资源字典中,构成界面的基本样式文件,然后进行不同颜色皮肤的定制. 即在新的皮肤资源字典文件中引入基本样式文件,然后使用资源继承,并且只设置控件的颜色属性等,形成一个皮肤文 ...

  9. Python IDLE背景主题

    相信刚进入python学习之路的朋友们,都还是挺喜欢python自带的IDLE,但是白的代码背景色以及其它的代码色确实让人看着有点不舒服,所以当时也琢磨着能不能自己给它换换颜色,这个当然可以,废话不多 ...

  10. Python从入门到实践 学习笔记(二)元祖686gffs

    列表是可以修改的,而不可变的列表被称为元组 . 定义 * 用圆括号来标识.定义元组后,使用索引来访问其元素,就像访问列表元素一样 修改变量 * 不能修改元组的元素,但可以给存储元组的变量赋值 修改元素 ...