跳到主要内容

GC 垃圾回收机制

问题

Android ART 虚拟机的垃圾回收机制是怎样的?

答案

ART GC 策略

ART 使用分代回收 + 并发复制策略:

GC 类型

GC 类型触发条件STW 时间
Young GC年轻代满< 1ms
Concurrent Copying堆使用率高~1ms(仅标记根)
Full GC内存严重不足较长(十几 ms)
Explicit GCSystem.gc()较长

GC Root 类型

从 GC Root 出发不可达的对象才会被回收。

引用类型

// 强引用 —— 不会被 GC
val user = User()

// 软引用 —— 内存不足时回收(适合缓存)
val softRef = SoftReference(Bitmap())

// 弱引用 —— 下次 GC 就回收
val weakRef = WeakReference(activity)

// 虚引用 —— 随时回收,用于跟踪 GC
val phantomRef = PhantomReference(obj, queue)

常见面试问题

Q1: Android 8.0 前后 Bitmap 的内存分配有何变化?

答案

版本Bitmap 像素数据影响
Android < 8.0Java Heap占用 Java 堆,容易 OOM
Android >= 8.0Native Heap不占 Java 堆,但仍占内存

8.0 后 Bitmap 使用 NativeAllocationRegistry 跟踪 Native 内存,GC 时一起释放。

Q2: 为什么不建议主动调用 System.gc()

答案

  1. ART 的 GC 已经非常高效,自动管理
  2. System.gc() 只是建议,不保证立即执行
  3. 可能触发 Full GC,造成全局 STW 暂停
  4. 如果频繁调用,反而影响性能

Q3: Finalizer 的问题是什么?

答案

重写 finalize() 的对象需要至少两次 GC 才能回收(第一次标记放入 Finalizer 队列,执行 finalize() 后第二次才回收),且 Finalizer 线程优先级低可能积压。现代 Android 推荐使用 CleanerPhantomReference

相关链接