Android 内存泄漏分析与解决
Android 内存泄漏分析与解决
常见内存泄漏场景与解决方案
目录
1. 内存泄漏基础
什么是内存泄漏
1 | 正常内存使用: |
内存泄漏的影响
- 应用卡顿: 垃圾回收频繁触发
- OOM 崩溃: 内存不足
- 电池消耗: GC 占用 CPU
2. 常见泄漏场景
| 场景 | 原因 | 解决方案 |
|---|---|---|
| 静态 View | View 持有 Activity 引用 | 使用 WeakReference |
| Handler | 延迟消息持有 Activity | 移除消息/使用弱引用 |
| 非静态内部类 | 隐式持有外部类引用 | 改为静态类/弱引用 |
| Thread | 线程持有 Activity | 使用 Lifecycle-aware 组件 |
| 监听器未移除 | 监听器持有对象引用 | 在 onDestroy 移除 |
| Adapter 未清理 | ViewHolder 持有 View | 使用 ViewBinding |
3. LeakCanary 使用指南
集成 LeakCanary
1 | // build.gradle (app) |
LeakCanary 工作原理
1 | ┌─────────────────────────────────────────────────────────────────────┐ |
典型泄漏报告解读
1 | ┌─────────────────────────────────────────────────────────────────────┐ |
4. 静态变量导致的泄漏
问题代码
1 | class MainActivity : AppCompatActivity() { |
静态 View 泄漏
1 | class MainActivity : AppCompatActivity() { |
解决方案
1 | class MainActivity : AppCompatActivity() { |
5. 非静态内部类与 Handler
Handler 泄漏
1 | class MainActivity : AppCompatActivity() { |
解决方案
1 | class MainActivity : AppCompatActivity() { |
内部类泄漏
1 | class MainActivity : AppCompatActivity() { |
6. 资源未关闭
常见未关闭资源
| 资源 | 后果 | 解决方案 |
|---|---|---|
| Cursor | 内存泄漏 | close() |
| Stream | 内存泄漏 | use {} |
| Bitmap | OOM | recycle() |
| 注册监听器 | 泄漏 | unregister() |
正确示例
1 | // ❌ 错误: 未关闭 Cursor |
文件流
1 | // ❌ 错误: 未关闭流 |
7. Compose 中的泄漏
remember 生命周期问题
1 |
|
DisposableEffect 正确清理
1 |
|
避免重组泄漏
1 |
|
内存分析工具
| 工具 | 用途 |
|---|---|
| LeakCanary | 自动检测 Activity/Fragment 泄漏 |
| Android Profiler | 实时内存监控 |
| MAT (Memory Analyzer Tool) | 深入分析堆内存 |
| jmap/jhat | 命令行内存分析 |
总结
1 | 内存泄漏检查清单: |
相关文章: