`

Android中的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中的软引用和弱引用

    在Android中,软引用和弱引用常用于图片缓存。例如,当我们加载大量图片时,为了避免内存溢出,可以使用软引用来保存图片对象,这样在内存不足时,这些图片会被自动移除,释放内存。而弱引用则更适合用于临时的、不...

    WeakDelegate,Weakreference财产委托提议.zip

    在IT行业中,尤其是在Android或Java开发中,弱引用(WeakReference)是一个重要的概念,它用于内存管理,防止内存泄漏。这个“WeakDelegate,Weakreference财产委托提议.zip”项目显然是一个Kotlin实现的开源项目,旨在...

    Java中的软引用弱引用和虚引用.docx

    ### Java中的软引用、弱引用和虚引用详解 #### 一、引言 在Java开发过程中,特别是Android应用开发中,经常会遇到一个普遍的问题——内存溢出(OutOfMemory Error,简称OOM)。这个问题往往与如何有效地管理内存...

    Android 软引用和弱引用详解及实例代码

    本文将深入讲解软引用(SoftReference)和弱引用(WeakReference)的概念、区别以及在Android开发中的应用场景,并提供实例代码。 软引用(SoftReference)是一种比强引用(Strong Reference)稍弱的引用类型,当...

    Android处理内存泄漏的代码例子

    可以使用弱引用(`WeakReference`)或软引用(`SoftReference`)来存储这些对象: ```java WeakReference&lt;Activity&gt; weakActivity = new WeakReference(activity); // 使用weakActivity.get()访问Activity // 当...

    Android利用软引用和弱引用避免OOM的方法

    总结起来,理解并熟练使用软引用和弱引用可以帮助Android开发者更有效地管理内存,降低OOM的风险。在设计缓存系统或者处理大型数据对象如Bitmap时,合理运用这些引用类型可以显著提升应用的性能和稳定性。

    Android的内存机制和溢出说明

    使用弱引用(WeakReference)或使用静态内部类可以避免这种问题。 4. **线程和Handler**:创建的线程或Handler实例若持有Activity引用,即使Activity已结束,线程仍在执行,就会导致内存泄露。线程应尽可能短生命...

    Android线程结束——合理的结束你想结束的线程

    2. **使用 WeakReference**:为了避免内存泄漏,可以将Activity引用弱引用化(WeakReference),当Activity被销毁时,AsyncTask不会阻止其回收。 3. **取消与重试策略**:如果任务需要取消,可以考虑设计重试机制,...

    java引用的demo

    弱引用通过`java.lang.ref.WeakReference`类表示,即使有弱引用指向对象,只要没有其他强引用,JVM在任何时候都可以回收该对象。这种引用类型在需要临时存储对象,但又不希望影响其生命周期的情况下非常有用。 最后...

    Java/Android引用类型及其使用全面分析

    Java和Android平台中,引用类型是理解内存管理的关键概念,主要分为四种:强引用、软引用、弱引用和虚引用。这些引用类型的特性各异,适用于不同的内存管理策略。 1. **强引用(Strong Reference)**是最常见的引用...

    android内存优化详解

    为避免这类问题,应避免使用静态变量引用Context,优先使用ApplicationContext,或者使用WeakReference弱引用。 线程也是引发内存泄露的常见原因。线程内部持有的对象如果长时间存活,可能会导致原本应被释放的对象...

    Android-语音通话时息屏的实现

    7. **弱引用锁(WeakLock)**:在压缩包中的`WeakLock`可能是指使用了Java的WeakReference机制来管理锁对象。在Android中,为了避免内存泄漏,尤其是在长时间运行的任务(如通话)中,可以使用弱引用锁来确保当不再有...

    android内存分析

    - 使用弱引用(WeakReference)来代替强引用,使得当对象不再被其他非弱引用持有时,可以被GC回收。 4. **线程导致的内存泄露** 线程也可能成为内存泄露的来源,因为它们可以创建并持有长时间存在的对象。例如,...

    androidStudio内存泄漏分析

    解决方案是避免在静态变量中存储非静态对象,或者使用弱引用(WeakReference)。 2. **单例模式**:不正确的单例实现可能导致内存泄漏。确保单例在适当时候被释放,或者使用依赖注入框架避免单例。 3. **匿名内部类...

    Android内存泄漏简介

    开发者应该遵循最佳实践,例如使用弱引用(WeakReference)来持有这些组件,或者在适当的生命周期内及时清理引用。 2. 资源对象没有关闭造成的内存泄漏 在Android开发中,资源对象如Cursor、File、Socket等,使用...

    Android代码-Android-performance-optimization

    - 使用弱引用:当对象不再使用时,通过WeakReference及时释放内存。 - 图片加载优化:使用Glide、Picasso等库进行图片加载和缓存管理。 3. Handler产生的内存泄露: - Handler内部会持有对Looper和MessageQueue...

    android dialogUtil

    同时,使用WeakReference来持有Activity的引用,确保当Activity被销毁时,弱引用不会阻止其被垃圾回收。 2. **在合适的时间初始化和显示Dialog**:通常在需要显示Dialog时才进行实例化,并确保在Activity的onCreate...

    android性能优化之内存泄露

    **解决策略**:将内部类声明为静态类,或者使用弱引用来代替直接引用。 ##### 5. 异步线程 异步线程中Handler的不当使用是导致内存泄露的常见原因。例如,Handler持有Activity的引用,但在Activity销毁后未能及时...

    Android-memroy.zip_android_android 优化

    使用WeakReference和SoftReference可以帮助开发者实现弱引用和软引用,让对象在内存不足时能被及时回收,防止内存泄漏。 4. **Bitmap优化** Bitmap是Android中消耗内存的主要因素之一。通过合理设置Bitmap的配置...

Global site tag (gtag.js) - Google Analytics