美文网首页
Android中的WeakReference 弱引用

Android中的WeakReference 弱引用

作者: longmingren123 | 来源:发表于2019-07-15 11:21 被阅读0次

    WeakReference 弱引用

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

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

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

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

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

    Handler mHandler = newHandler() {

        @Override

        publicvoidhandleMessage(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

     */

    publicclassAsyncDrawable extendsBitmapDrawable {

        privatefinalWeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;

        publicAsyncDrawable(Resources res, Bitmap bitmap,

                BitmapWorkerTask bitmapWorkerTask) {

            super(res, bitmap);

            // bitmapWorkerTaskReference实例关联BitmapWorkerTask

            bitmapWorkerTaskReference = newWeakReference<BitmapWorkerTask>(

                    bitmapWorkerTask);

        }

        publicBitmapWorkerTask getBitmapWorkerTask() {

            returnbitmapWorkerTaskReference.get();

        }

    }

    此时

    WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference 关联了

    bitmapWorkerTask 实例(可认为两者是“好朋友”关系);在虚拟机看来 bitmapWorkerTask 实例是垃圾时,但

    WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference

    不是垃圾。但垃圾并不会立即被回收,也就是仍然可以使用对象 bitmapWorkerTask

    实例;若该对象已被清理,则必须重新构建对象,并再一次关联。

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

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

    相关文章

      网友评论

          本文标题:Android中的WeakReference 弱引用

          本文链接:https://www.haomeiwen.com/subject/uhwgkctx.html