Android中的WeakReference 弱引用

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回收掉。

时间: 2024-10-04 18:26:03

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

说说WeakReference弱引用

WeakReference弱引用概述 http://www.cnblogs.com/xrq730/p/4836700.html,关于Java的四种引用状态具体请参看此文 Java里一个对象obj被创建时,被放在堆里.当GC运行的时候,发现没有任何引用指向obj,那么就会回收obj对象的堆内存空间. 但是现实的情况时,写代码的时候,往往通过把所有指向某个对象的引用置空来保证这个对象在下次GC运行的时候被回收: Object obj = new Object(); obj = null; 这种方式说

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

在Android开发中,基本上很少有用到软引用或弱引用,这两个东东若用的很好,对自己开发的代码质量的提高有很大的帮助.若用的不好,会坑了自己.所以,在还没有真正的去了解它们之前,还是慎用比较好. 下面将通过两个Demo来结识软引用和弱引用在开发中的运用. 一. WeakReference:防止内存泄漏,要保证内存被虚拟机回收. 下面以一个时间更新的Demo来说明弱引用的运用. 1. main.xml文件代码如下: [html] view plaincopy <?xml version="1

C#WeakReference弱引用

弱引用:在引用对象的同时,允许垃圾回收该对象. .NET中提供了WeakReference对象来实现这个功能. 对于那些创建便宜但耗费大量内存的对象,即希望保持该对象,又要在应用程序需要时使用, 同时希望GC必要时回收时,可以考虑使用弱引用.弱引用使用起来很简单, WeakReference w = new WeakReference(xml);//创建若引用对象 if (w.IsAlive)//判断是否已被垃圾回收 { XmlDocument xml1 = w.Target as XmlDoc

lua中对象的弱引用

几次编写lua时.总是有同事遇到A中对象已经释放了.但B对象中A对象的值不是为空的. Lua的gc和Java的类似.只有当对象没有被引用时候才会释放这块内存.要想实现A释放了B中A的值也释放了这时候需要用到弱引用. setmetatable(t,{__mode="k"}); __mode 的值可以为"k","v","kv" ~ ~第一段代码中可以看到内存中是有一个[key]保存了一个table.虽然b=nil了但是t中还是存在

java中的弱引用软引用和虚引用

在java中的java.lang.ref包中定义了三个引用类,分别是软引用.弱引用.和虚引用.这3个类提供了一种便捷的机制让我们可以和垃圾回收机制交互,同时也为缓存提供了一种机制,那么这三个类导致有什么作用呢? SoftReference: 如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它:如果内存空间不足了,就会回收这些对象的内存.只要垃圾回收器没有回收它,该对象就可以被程序使用.软引用可用来实现内存敏感的高速缓存(下文给出示例). 软引用可以和一个引用队列(Reference

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

对于Java中的垃圾回收机制来说,对象是否被回收的标准在于该对象是否被引用.因此,引用也是JVM进行内存管理的一个重要概念. Java中对象的引用一般有以下4种类型: 1强引用  2软引用  3弱引用  4虚引用 以下一一介绍其用法和区别 1强引用:在Java中最常见的就是强引用,把一个对象赋给一个引用变量,这个引用变量就是一个强引用.当一个对象被强引用变量引用时,它处于可达状态,它是不可能被垃圾回收机制回收的,即使该对象以后永远都不会被用到JVM也不会回收.因此强引用是造成Java内存泄漏的主

Java中强引用、软引用、弱引用

Java 中强引用, 软引用SoftReference,弱引用WeakReference,虚引用 Java当中的引用有四种: 1.强引用  平常我们用的最多的引用. 强引用是使用最普遍的引用.如果一个对象具有强引用,那垃圾回收器绝不会回收它.当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题.只有当分配的内存对象不再有任何引用时,GC才可能开始回收其内存. <span style="font-si

4中引用(强,软,弱,虚)侧重弱引用

1,强引用,对象有强引用与之关联,即使在内存不足,抛出OutOfMemory错误也不会回收这种对象 2,软引用是用来描述一些有用但并不是必需的对象,java.lang.ref.SoftReference类来表示. 对于软引用关联着的对象,只有在内存不足的时候JVM才会回收该对象.可以很好地用来解决OOM的问题,适合用来实现缓存:比如网页缓存.图片缓存等. 软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被JVM回收,这个软引用就会被加入到与之关联的引用队列

OC 中的强引用(strong referene)和弱引用( weak reference)

关于oc中的强弱引用,有需要的朋友可以参考下. 强引用和弱引用的广义区别 强引用也就是通常所讲的引用,其存亡直接决定了所指对象的存亡.如果不存在指向一个对象的引用,并且此对象不再显示列表中,则此对象会被从内存中释放.弱引用除了不决定对象的存亡外,其他与强引用相同.即使一个对象被持有无数个若引用,只要没有强引用指向他,那么其还是会被清除 简单来说,strong等同retain(ARC之前),而weak和assign,weak比assign多了一个功能,当对象消失后自动把指针变成nil. __wea