Framework 补完计划 (8):LowMemoryKiller 与进程管理 —— 掌握全栈 App 的生存法则

18 阅读2分钟

前言

历经七篇深挖,我们聊过了渲染、交互和虚拟机。今天是大结局,我们回到最现实的问题:你的 App 凭什么能一直活着?

在资源有限的手机系统中,后台进程随时面临被处决的风险。作为一个拥有 Ktor 后端(Server)和 Native 库的全栈 App,我们该如何在这套残酷的法则下生存?


一、 判官:LowMemoryKiller (LMK)

当系统内存告急时,Linux 内核的 oom_killer 已经太迟了。Android 引入了 LMK

  • oom_score_adj:这是每一个进程的“死亡笔记”评分。分越高,死得越快。

二、 进程等级:决定谁先消失

系统将进程划分为几个严苛的等级:

  1. 前台进程 (Foreground):正在屏幕上显示的 App(评分最低,最安全)。
  2. 可见进程 (Visible):被透明浮窗遮挡,或部分可见。
  3. 服务进程 (Service):后台运行的 Service
  4. 缓存进程 (Cached):用户已经滑掉的 App(评分最高,秒杀)。

三、 全栈架构的生存挑战

在你的 KMP-Clean-MVI 项目中,面临以下独特挑战:

  1. Ktor Server 的宿命:如果你在 Android 端启动了嵌入式服务器,请务必将其运行在 Foreground Service 中,并显示通知。否则,一旦用户切出 App,你的 API 服务会立刻因“Cached 进程”被杀。
  2. Native 内存的隐形压力:LMK 很难精准计算出 C 库(JNI 申请的直接内存)的具体占用。如果你的 C 库占用过大,系统会发现总可用内存暴跌,从而开始无差别大面积清理。

四、 老兵的“保活”与“自律”

  1. 自救:监听 onTrimMemory 回调。当系统发出信号时,主动释放图片缓存、断开不必要的 Ktor 客户端连接。
  2. 状态保存:在 Compose 导航中,利用 rememberSaveable。这样即使进程被杀重启,用户依然能回到之前的页面。
  3. 优雅降级:后端任务(KMP 协程)不要在 Activity 销毁后无限运行。使用 viewModelScope 确保任务与 UI 寿命同步。

五、 源码及分析

  • drivers/staging/android/lowmemorykiller.c:内核层源码。
  • com.android.server.am.ProcessList:Framework 层管理评分的逻辑。

结语:全系列总结

恭喜你!走完了《Framework 补完计划》的八篇硬核之旅。

  1. 我们从 Choreographer 掌握了时间的节拍。
  2. 通过 BufferQueue 梳理了像素的物流。
  3. 直面 HWC 的硬件真相。
  4. 打通了 Input 全链路的神经反射。
  5. 揭秘了 Handler 异步的本质。
  6. 计算了 JNI & Binder 的跨界成本。
  7. 洞察了 ART 虚拟机 的运作逻辑。
  8. 最后,我们掌握了 LMK 的生存法则。

欢迎访问我的开源项目:KMP-Clean-MVI


后面准备针对Compose 渲染底层源码进行知识补全,从底层解释为什么 Compose 性能好,如果遇到 UI 掉帧,我们该怎么办,敬请期待!