前言
Compose 的声明式风格带来了一个副作用:对象爆炸。
每次重组,大量的 Modifier、状态包装类和临时闭包都会被创建。
作为资深Android开发,我们对 JVM 的 GC(垃圾回收)并不陌生。但 ART (Android Runtime) 针对移动设备的内存和功耗做了极其精密的定制。今天我们看看它如何支撑 Compose 的运行。
一、 ART 的核心进化:从 JIT 到 AOT
- Dalvik 时代:全靠解释执行。
- ART AOT (Android 5.0+):安装时就编成机器码,快但占空间。
- ART 混合模式 (Android 7.0+):平时 JIT(热点代码编译),空闲时 AOT。这种模式让你的全栈 App 在频繁更新后依然保持流畅。
二、 GC 策略:对抗“内存抖动”
Compose 的运行会产生海量的短命对象。ART 使用了 分代回收 (Generational GC) 策略:
- 年轻代 (Young Generation):大部分 Compose 对象诞生即死亡。ART 采用快速的“标记-复制”算法,回收开销极低。
- 并发标记 (Concurrent Marking):现代 ART 几乎不会为了 GC 停止(Stop-the-world)UI 线程。它在后台悄悄标记那些不再使用的对象。
三、 内存泄露的“新姿势”
在 Compose 混编项目中,老兵需要警惕:
- 闭包捕获:Composable 中的 lambda 容易捕获外部的 ViewModel 或 Context。
- CompositionLocal:如果注入了巨大的对象且没设置合理的默认值,会导致内存积压。
四、 KMP 中的“异构内存”
在你的全栈项目中,你面对的是两套内存管理系统:
- Android (ART):自动 GC,比较宽松。
- iOS (Kotlin/Native):基于 ARC (自动引用计数) 的定制算法。
老兵 Tips:在 iOS 上,Kotlin 对象的回收时机比 Android 更早、更频繁。这也是为什么在 commonMain 写代码时要尽量避免循环引用。
五、 源码及分析工具
art/runtime/gc/:ART 垃圾回收器的核心实现。- Android Studio Memory Profiler:观察“内存阶梯图”,你会发现 Compose 的分配非常密集,但回收也非常迅速。
结语
理解了虚拟机,你就明白为什么说 Compose 是“拿空间换开发效率”。只要我们遵循 @Stable 和单向数据流的原则,ART 完全有能力处理好这些“甜蜜的负担”。
下一篇,我们将进入本计划的大结局 —— LowMemoryKiller 与进程管理:让你的全栈 App 活得更久。