WeakReference 弱引用

定义:弱引用,与强引用(我们常见的引用方式)相对;特点是:GC在回收时会忽略掉弱引用对象(忽略掉这种引用关系),即:就算弱引用指向了某个对象,但只要该对象没有被强引用指向,该对象也会被GC检查时回收掉。

强引用实例自然不会被GC回收!

如何引出弱引用?弱引用的实际用途是什么?

什么是内存泄漏?Java使用有向图机制,通过GC自动检查内存中的对象;如果GC发现一个或一组对象为不可达的状态,则将该对象从内存中回收。也就是说:一个对象不被任何引用所指向,则该对象会在被GC发现的时候回收。

可能导致内存泄漏的实例:

    Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
mImageView.setImageBitmap(mBitmap);
};
};

当使用内部类(或者匿名类)来创建Handler的时候,Handler对象会隐式地持有一个外部类的对象(通常是Activity)的引用(否则怎么可能通过Handler来操作Activity的View?)。而Handler通常会伴随着一个耗时的后台线程(比如:拉取网络图片);该后台线程在任务执行完毕后,通过消息机制通知Handler,然后Handler把图片更新到界面上。假设用户在网络请求过程中关闭了Activity,正常情况下这个Activity不再被使用,就有可能被GC回收;但此时线程尚未执行完毕,而该线程持有Handler的引用(不然怎么发送消息给Handler?),Handler又持有Activity的引用,就导致该Activity无法被回收(内存泄漏),直到网络请求结束(如:图片下载完毕)。另外如果执行了Handler的postDelayed(),该方法会将Handler装入一个Message,并把该Message推到MessageQueue中,由此产生了一条链式结构:MessageQueue->Message->Handler->Activity,导致Activity被持有引用而无法被回收。(总结:实例对象被其他对象持有引用,而无法被回收)

内存泄漏的危害是什么?内存泄漏会引发虚拟机占用内存过高。对于Android应用程序来说,用户打开一个Activity,使用完之后关闭,内存泄漏;执行上述步骤多次,程序占用内存超过系统限制。

如何避免内存泄漏?可以使用什么方法?由此引出了弱引用。

用于非必需对象,被弱引用关联的对象只能生存到下一次GC发生之前。当GC工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。

/**
* <功能描述> 用于加载Bitmap实例
*
* @author Administrator
*/
public class AsyncDrawable extends BitmapDrawable {
private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
public AsyncDrawable(Resources res, Bitmap bitmap,
BitmapWorkerTask bitmapWorkerTask) {
super(res, bitmap);
// bitmapWorkerTaskReference实例关联BitmapWorkerTask
bitmapWorkerTaskReference = new WeakReference<BitmapWorkerTask>(
bitmapWorkerTask);
}
public BitmapWorkerTask getBitmapWorkerTask() {
return bitmapWorkerTaskReference.get();
}
}

此时 WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference 关联了 bitmapWorkerTask 实例(可认为两者是“好朋友”关系);在虚拟机看来 bitmapWorkerTask 实例是垃圾时,但 WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference 不是垃圾。但垃圾并不会立即被回收,也就是仍然可以使用对象 bitmapWorkerTask 实例;若该对象已被清理,则必须重新构建对象,并再一次关联。

好处在于:可以申请任意多个 bitmapWorkerTask 实例对象,并与弱引用对象关联;使用前,先判断是否已被释放;如果已被释放,则重新申请;若未被释放,则直接使用。WeakReference负责了释放规则。

使用了上述代码后,用户在关闭Activity之后,就算后台线程还没有结束,但由于仅有一个来自Handler的弱引用指向Activity,所有GC仍然会在检查的时候把Activity回收掉。

Android中的WeakReference 弱引用的更多相关文章

  1. 说说WeakReference弱引用

    WeakReference弱引用概述 http://www.cnblogs.com/xrq730/p/4836700.html,关于Java的四种引用状态具体请参看此文 Java里一个对象obj被创建 ...

  2. C#WeakReference弱引用

    原文:C#WeakReference弱引用 弱引用:在引用对象的同时,允许垃圾回收该对象. .NET中提供了WeakReference对象来实现这个功能. 对于那些创建便宜但耗费大量内存的对象,即希望 ...

  3. android WeakReference(弱引用 防止内存泄漏)与SoftReference(软引用 实现缓存机制(cache))

    在Android开发中,基本上很少有用到软引用或弱引用,这两个东东若用的很好,对自己开发的代码质量的提高有很大的帮助.若用的不好,会坑了自己.所以,在还没有真正的去了解它们之前,还是慎用比较好. 下面 ...

  4. WeakReference 弱引用

    弱引用是使用WeakReference类创建的.因为对象可能在任意时刻被回收,所以在引用该对象前必须确认它存在. class MainEntryPoint { static void Main() { ...

  5. java中的强引用(Strong reference),软引用(SoftReference),弱引用(WeakReference),虚引用(PhantomReference)

    之前在看深入理解Java虚拟机一书中第一次接触相关名词,但是并不理解,只知道Object obj = new Object()类似这种操作的时候,obj就是强引用.强引用不会被gc回收直到gc roo ...

  6. Android 弱引用和软引用

    软引用 和 弱引用 1.  SoftReference<T>:软引用-->当虚拟机内存不足时,将会回收它指向的对象:需要获取对象时,可以调用get方法. 2.  WeakRefere ...

  7. Java中的四种引用类型,强引用,软引用,弱引用,虚引用

    对于Java中的垃圾回收机制来说,对象是否被回收的标准在于该对象是否被引用.因此,引用也是JVM进行内存管理的一个重要概念. Java中对象的引用一般有以下4种类型: 1强引用  2软引用  3弱引用 ...

  8. java 中的三种引用,强引用,软引用,弱引用

    StrongReference   前引用,不会被系统GC回收,系统宁愿跑出OOM异常也不会回收强引用 SoftReference  软引用,在系统内存不足的时候,会被GC回收 WeakReferen ...

  9. Android中使用Handler造成内存泄露的分析和解决

    什么是内存泄露?Java使用有向图机制,通过GC自动检查内存中的对象(什么时候检查由虚拟机决定),如果GC发现一个或一组对象为不可到达状态,则将该对象从内存中回收.也就是说,一个对象不被任何引用所指向 ...

随机推荐

  1. 洛谷P4719 动态dp

    动态DP其实挺简单一个东西. 把DP值的定义改成去掉重儿子之后的DP值. 重链上的答案就用线段树/lct维护,维护子段/矩阵都可以.其实本质上差不多... 修改的时候在log个线段树上修改.轻儿子所在 ...

  2. css实现弹出框

    弹出框也是前端里面经常使用的一个应用场景了,最开始想到的是用js实现这个效果,看到codepen上面有用css实现的.其实就是用到了css里面的一个:target选择器+visibility属性. U ...

  3. Day049--jQuery的文档操作和事件介绍

    今日内容 DOM操作(CRUD) js中DOM document.createElement('p') appendChild() insertBefore() removeChild() 创建元素 ...

  4. linux c编程之fcntl

    fcntl可实现对指定文件描述符的各种操作,其函数原型如下: int fcntl(int fd, int cmd, ... /* arg */ ); 其中,操作类型由cmd决定.cmd可取如下值: F ...

  5. go interface接口

    一:接口概要 接口是一种重要的类型,他是一组确定的方法集合. 一个接口变量可以存储任何实现了接口方法的具体值.一个重要的例子就是io.Reader和io.Writer type Reader inte ...

  6. ArcGis 属性表.dbf文件使用Excel打开中文乱码的解决方法

    2019年4月 拓展: ArcGis——好好的属性表,咋就乱码了呢? 2019年3月27日补充: 在ArcMap10.3+(根据官网描述应该是,作者测试使用10.5,可行)以后的版本,可以使用ArcT ...

  7. oldboy s21day12.设计商城系统,主要提供两个功能:商品管理、会员管理。

    #!/usr/bin/env python# -*- coding:utf-8 -*- # 1.写出三元运算的基本格式及作用?'''a if a>b else b''' # 2.什么是匿名函数? ...

  8. 多人聊天室(Java)

    第1部分 TCP和UDP TCP:是一种可靠地传输协议,是把消息按一个个小包传递并确认消息接收成功和正确才发送下一个包,速度相对于UDP慢,但是信息准确安全:常用于一般不要求速度和需要准确发送消息的场 ...

  9. 查看和设置MySQL数据库字符集(转)

    查看和设置MySQL数据库字符集作者:scorpio 2008-01-21 10:05:17 标签: 杂谈 Liunx下修改MySQL字符集:1.查找MySQL的cnf文件的位置find / -ina ...

  10. DCM、PLL、PMCD、MMCM相关

    摘自网上 : http://xilinx.eetop.cn/viewnews-1482 The DCM is a Digital Clock Manager - at its heart it is ...