从"被动杀后台"到"主动设上限"
此前的 Android 一直用"被动杀后台"策略:系统内存不够时,按优先级回收进程。这个机制的问题在于不可预测——开发者很难判断自己的 app 什么时候会被杀。
Android 17 改成了"主动设上限":根据设备总 RAM,给每个 app 设定一个内存硬上限。这个上限追踪的是"已分配匿名内存"(anonymous memory),基本就是堆+本地缓冲区。一旦超过,进程直接被终止,不留堆栈跟踪。
Google 官方说这个限制在首版中"设置得比较保守",目标是极端内存泄漏和异常消耗,而非正常 workload。但"保守"不等于"不存在"——这是一个硬限制,不是建议。目前仅在部分设备上生效。

如何知道自己被杀了?
被内存限制杀掉的 app,在 ApplicationExitInfo 中的表现为:
getReason() == REASON_OTHERgetDescription()包含"MemoryLimiter:AnonSwap"
这个字符串是唯一可靠的判断信号。Google 建议在 Application.onCreate 中注册检查,否则你可能根本不知道自己的 app 在用户设备上被静默杀掉了。
Google 给的开发者工具
ProfilingManager 异常触发器
新增 TRIGGER_TYPE_ANOMALY,支持在生产环境中捕获异常时的堆转储(heap dump),包括 OOM 和内存限制触发场景。回调在系统执行终止之前触发,开发者有机会收集调试数据。此外还新增了 COLD_START、OOM、KILL_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 暂停成本
- 无锁 MessageQueue:
android.os.MessageQueue新增无锁实现,减少丢帧 - 通知内存限制:自定义通知视图也加了严格大小限制,防止大图通知吃内存
开发者该怎么做?
- 启用 R8 优化,缩减常驻代码体积
- 图片加载优先用 RGB_565 等低内存格式,及时回收位图
- 用 LeakCanary 修复内存泄漏(Android Studio Panda 已内置集成)
- 在 Activity 中响应
onTrimMemory回调,主动释放界面缓存 - 在
Application.onCreate中检查ApplicationExitInfo,监控是否被内存限制杀掉 - 在低端设备或模拟器上用
am memory-limiter主动压测
来源:Android Developers Blog | Android 17 Release Notes | Stora