题目
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 Context2. 非静态内部类持有外部引用
// 错误示例
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'
}分析流程:
- 自动检测Activity/Fragment销毁后未回收对象
- 生成堆转储文件(.hprof)
- 展示引用链路径图,高亮泄漏根源
四、最佳实践
- 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后检查