Android 17 强制限制 App 内存:超限直接终止,Google 倒逼开发者优化

从"被动杀后台"到"主动设上限"

此前的 Android 一直用"被动杀后台"策略:系统内存不够时,按优先级回收进程。这个机制的问题在于不可预测——开发者很难判断自己的 app 什么时候会被杀。

Android 17 改成了"主动设上限":根据设备总 RAM,给每个 app 设定一个内存硬上限。这个上限追踪的是"已分配匿名内存"(anonymous memory),基本就是堆+本地缓冲区。一旦超过,进程直接被终止,不留堆栈跟踪。

Google 官方说这个限制在首版中"设置得比较保守",目标是极端内存泄漏和异常消耗,而非正常 workload。但"保守"不等于"不存在"——这是一个硬限制,不是建议。目前仅在部分设备上生效。

Android 17 内存限制机制示意

如何知道自己被杀了?

被内存限制杀掉的 app,在 ApplicationExitInfo 中的表现为:

  • getReason() == REASON_OTHER
  • getDescription() 包含 "MemoryLimiter:AnonSwap"

这个字符串是唯一可靠的判断信号。Google 建议在 Application.onCreate 中注册检查,否则你可能根本不知道自己的 app 在用户设备上被静默杀掉了。

Google 给的开发者工具

ProfilingManager 异常触发器

新增 TRIGGER_TYPE_ANOMALY,支持在生产环境中捕获异常时的堆转储(heap dump),包括 OOM 和内存限制触发场景。回调在系统执行终止之前触发,开发者有机会收集调试数据。此外还新增了 COLD_STARTOOMKILL_EXCESSIVE_CPU_USAGE 三种触发类型。

adb 测试命令

开发者可以用 am memory-limiter 命令手动测试:

  • am memory-limiter ignore [UID|all|none] — 跳过限制
  • am memory-limiter manual [PID|max|none] [MB] — 手动设限
  • am memory-limiter status — 查看当前状态

配套的运行时优化

Android 17 还带来了一些运行时层面的优化:

  • 分代 GC:ART 的 Concurrent Mark-Compact 收集器支持分代垃圾回收,优先回收"年轻代"对象,降低 GC 暂停成本
  • 无锁 MessageQueueandroid.os.MessageQueue 新增无锁实现,减少丢帧
  • 通知内存限制:自定义通知视图也加了严格大小限制,防止大图通知吃内存

开发者该怎么做?

  1. 启用 R8 优化,缩减常驻代码体积
  2. 图片加载优先用 RGB_565 等低内存格式,及时回收位图
  3. 用 LeakCanary 修复内存泄漏(Android Studio Panda 已内置集成)
  4. 在 Activity 中响应 onTrimMemory 回调,主动释放界面缓存
  5. Application.onCreate 中检查 ApplicationExitInfo,监控是否被内存限制杀掉
  6. 在低端设备或模拟器上用 am memory-limiter 主动压测

来源:Android Developers Blog | Android 17 Release Notes | Stora

相关推荐