侧边栏壁纸
博主头像
colo

欲买桂花同载酒

  • 累计撰写 1823 篇文章
  • 累计收到 0 条评论

Android内存泄漏场景分析及优化方案

2025-12-11 / 0 评论 / 5 阅读

题目

Android内存泄漏场景分析及优化方案

信息

  • 类型:问答
  • 难度:⭐⭐

考点

内存泄漏原理,LeakCanary使用,弱引用应用,生命周期管理

快速回答

Android内存泄漏常见场景及解决方案:

  • 静态引用Context/View:使用Application Context替代Activity Context
  • 非静态内部类:改为静态内部类+弱引用持有外部类
  • Handler延迟任务:Activity退出时清除MessageQueue
  • 监听器未注销:在对应生命周期注销监听

检测工具:LeakCanary集成,分析堆转储报告

解析

一、内存泄漏原理

当对象不再被使用时,因被GC Root引用导致无法回收,持续占用内存。常见GC Root包括:

  • 静态变量
  • 线程栈中的局部变量
  • JNI全局引用

二、典型泄漏场景与解决方案

1. 静态Context引用

// 错误示例
public class AppUtils {
    private static Context sContext;  // 可能持有Activity引用

    public static void init(Context context) {
        sContext = context; 
    }
}

修复方案:

sContext = context.getApplicationContext();  // 使用Application Context

2. 非静态内部类持有外部引用

// 错误示例
public class MainActivity extends Activity {
    private Runnable mTask = new Runnable() {
        @Override public void run() { /*...*/ } // 隐式持有Activity实例
    };
}

修复方案:

// 改为静态内部类+弱引用
private static class MyRunnable implements Runnable {
    private WeakReference<MainActivity> mActivityRef;

    MyRunnable(MainActivity activity) {
        mActivityRef = new WeakReference<>(activity);
    }

    @Override public void run() {
        MainActivity activity = mActivityRef.get();
        if (activity != null) { /* 操作activity */ }
    }
}

3. Handler延迟消息

// 正确做法
@Override
protected void onDestroy() {
    super.onDestroy();
    mHandler.removeCallbacksAndMessages(null);  // 清除所有消息
}

4. 监听器未注销

// 在Activity中
@Override
protected void onStart() {
    super.onStart();
    SensorManager.registerListener(this, sensor, rate);
}

@Override
protected void onStop() {
    super.onStop();
    SensorManager.unregisterListener(this);  // 必须成对注销
}

三、检测工具实践(LeakCanary)

集成步骤:

dependencies {
  debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.9.1'
}

分析流程:

  1. 自动检测Activity/Fragment销毁后未回收对象
  2. 生成堆转储文件(.hprof)
  3. 展示引用链路径图,高亮泄漏根源

四、最佳实践

  • Context使用原则:优先使用Application Context
  • 资源释放:Bitmap.recycle(),Cursor/Stream.close()
  • 架构优化:ViewModel+LiveData自动管理生命周期
  • 集合清理:及时移除无用的集合元素

五、常见错误

  • 在Fragment中直接使用getActivity()而不检查isAdded()
  • 单例模式持有Activity引用
  • WebView未单独销毁:
    // 在Activity中
    @Override
    protected void onDestroy() {
        mWebView.destroy();
        mWebView = null;
        super.onDestroy();
    }

六、扩展知识

  • 内存分析工具:Android Profiler, MAT(Memory Analyzer Tool)
  • 弱引用类型
    • WeakReference:GC时立即回收
    • SoftReference:内存不足时回收
  • LeakCanary原理:通过RefWatcher监控对象,利用KeyedWeakReference触发GC后检查