Android 内存管理

深入理解 Android 内存管理:JVM 内存模型、垃圾回收与泄漏排查实战。

核心问题

对象什么时候会被回收?

理解这个问题,就理解了内存管理的核心。


知识脉络

第一层:JVM 内存结构

┌─────────────────────────────────────────┐
│              JVM 内存                    │
├──────────────┬──────────────────────────┤
│   新生代      │         老年代           │
│  (Young Gen) │       (Old Gen)          │
├─────┬───┬────┤                          │
│Eden │S0 │ S1 │                          │
└─────┴───┴────┴──────────────────────────┘
  8    1   1        (默认比例)

对象晋升

  1. 新对象 → Eden
  2. Minor GC → 存活对象 → Survivor
  3. 年龄 ≥ 15 → Old Gen

第二层:垃圾回收

可达性分析

GC Roots 出发,遍历引用链,不可达的对象可回收。

GC Roots

  • 栈中引用
  • 静态变量
  • JNI 引用

GC 算法

算法优点缺点
标记-清除简单碎片
复制无碎片内存利用率低
标记-整理无碎片整理耗时

Android GC (ART)

  • 前台 GC:部分暂停,用户可见
  • 后台 GC:完整清理

第三层:内存泄漏

常见场景

场景原因解决
静态变量持有 Context生命周期不匹配Application Context
内部类隐式持有外部类静态内部类 + 弱引用
HandlerMessage 队列持有onDestroy 清理
注册未取消观察者未注销及时 unregister

检测工具

  • LeakCanary:自动检测
  • Memory Profiler:Heap Dump
  • MAT:分析 hprof

面试高频点

Q1: 四种引用类型?

类型回收时机用途
强引用永不普通
软引用内存不足缓存
弱引用下次 GC避免泄漏
虚引用随时跟踪回收

Q2: 内存抖动是什么?

频繁创建/销毁对象导致频繁 GC,表现为卡顿。

解决:对象复用、避免循环内创建。

Q3: OOM 排查步骤?

  1. Memory Profiler 查看内存分布
  2. 导出 hprof 分析大对象
  3. 检查 Bitmap、List 等大内存使用
  4. LeakCanary 检测泄漏

知识关联