Google Play 与 Android 17 内存治理:市场格局与趋势分析

2026 年 8 月,Google 在 Android Developers Blog 连发两篇与应用内存直接相关的文章:一篇讲 Android 17 向全 RAM 档位扩展 per-app memory limits,另一篇宣布 Google Play 新的质量门槛,覆盖内存占用、DEX 优化和换机 Zero-Tap Sign-In。细则在 Play Console 技术质量要求文档里(公告日 2026-08-26)。

如果你只跟了其中一篇,很容易误判自己有没有风险。

Memory Limiter 是设备上当场发生的事。用户可能只觉得「卡了一下回到桌面」,Vitals 曲线也未必立刻掉头------因为那是单次会话的尖峰。Play 门槛是另一套算法:28 天、90 分位、按 RAM 档和进程状态分桶。开发机测不出,单机峰值也代表不了。两件事叠在一起,才是完整图景:系统层 cgroup 限流,商店层 P90 卡 bad behavior。

Google 把背景归到内存硬件供应约束,新机 RAM 不再一味往上堆。这话可信不可信另说,但用户评判标准确实没变。卡顿、闪退、换机要重新登录,照样会打低分、卸载。做 App 的人得先分清三件事:谁在杀进程、谁在降可见度、自己手头该先量哪几个数。


第 1 章 双轨治理:系统 Memory Limiter 与 Play bad behavior

维度 Android 17 Memory Limiter Google Play 质量门槛
生效逻辑 单应用超 cgroup 预算 → zRAM 换页 → 可能杀进程 28 天 P90 超阈值 → bad behavior
主要信号 ApplicationExitInfoREASON_OTHER + MemoryLimiter:AnonSwap Android vitals:Anonymous RSS + Swap、Bitmap、DEX 优化占比
首批节奏 Pixel 起,向 4GB~16GB+ 扩展 2027-02 内存/DEX;2027-04 Zero-Tap Sign-In
未达标后果 卡顿、无栈终止 可见度与发布能力可能下调

系统侧保整机响应,商店侧用人口级采样逼长期优化。Limiter 管单次会话里的 outlier,Vitals 抓持续高占用的应用组合,两边不重复------但用户体感上可能分不清是哪一种在起作用。

走一遍真实链路

假设某信息流 App 在 4 GB 机上后台留了 250 MB Bitmap,同时 Anonymous RSS 顶到 1.2 GB:

  • 系统侧 :若当次会话 cgroup 预算被突破,先 zRAM 换页,用户刷列表时感到掉帧;再涨则进程被 terminate,ApplicationExitInfo 里出现 MemoryLimiter:AnonSwap,Crashlytics 可能无记录。
  • 商店侧:28 天窗口里,4 GB 档 Background 的 Anonymous RSS P90 上限是 1 GB,Bitmap P90 上限是 200 MB------两条线都可能记 bad behavior,且彼此独立。

同一份内存问题,可能在一天内让用户觉得「卡」,在一个月内让 Console 飘黄。只修其中一个维度,另一个照样找上门。

跟 LMK 别混

LMK / lmkd Memory Limiter Play Vitals
触发条件 系统整体内存压力 单应用超 cgroup 匿名内存预算 28 天 P90 超阈值
选择对象 按 adj 等挑 victim 约束 UID ≥ 10000 的应用,无白名单 按 App/Game、RAM 档、进程状态分桶
典型信号 低 adj 进程先死 MemoryLimiter:AnonSwap Console bad behavior 标记
开发者误区 「又是杀后台」 当成 OOM 查 用开发机峰值自证合格

对外沟通时别随口说成「又是 LMK 杀后台」。机制讲错了,排障方向也会偏。

关于 bad behavior 之后「可见度下调」具体怎么执行,官方目前给的是方向性描述,细到每个品类降多少、持续多久,还得靠后续案例和 Console 里的实际反馈来校准。排期时别假设「离阈值还有一点余量就安全」------P90 看的是尾部用户,尾部往往集中在低端机和长会话场景。


第 2 章 Memory Limiter 如何工作:先换页,再终止

官方描述超额占用是渐进的,分两步:

  1. zRAM Swapping :进程碰到 memory.high,内核对对应 cgroup 做定向回收,匿名页压进 zRAM。进程不一定马上死,但压缩/解压吃 CPU,用户侧常见 UI jank。
  2. 进程终止:zRAM 之后内存还在涨,系统 terminate 进程。

很多团队的第一反应是查 OOM 或 Java crash,这里往往对不上。字段口径跟 Play 的 Anonymous RSS + Swap 一个方向:看应用私有数据(Java/Kotlin 堆、native 分配、匿名映射),不是盯 Java 堆 MAX 就够。图片库、WebView、native 泄漏,都可能在堆指标「正常」时把匿名内存顶上去。

现场怎么认

ApplicationExitInfo.getDescription(),出现 MemoryLimiter:AnonSwap 就是 Memory Limiter 介入。启动时扫一遍历史记录,成本很低,收益很高:

kotlin 复制代码
val exits = activityManager.getHistoricalProcessExitReasons(packageName, 0, 20)
exits.filter {
    it.reason == ApplicationExitInfo.REASON_OTHER &&
    it.description?.contains("MemoryLimiter:AnonSwap") == true
}.forEach { exit ->
    // 上报:timestamp、rss、进程状态、前后台切换上下文
    logLimiterExit(exit)
}

这类终止往往没有传统 crash 栈,Crashlytics 里也可能干干净净。用户反馈「用着用着突然回桌面」,客服工单却找不到对应崩溃------多半就是这类信号没接上。

本地压测

ADB am memory-limiter 可以在 Android 17 设备上手动逼近上限(status 看当前策略,manual 对指定 PID 设 cap)。压测能复现「先卡后死」,比等线上用户碰运气靠谱。

另一点容易忽略:Android 17 起应用还没有运行时 API 能查平台分配的 memory limit。你只能估、只能压,没法在代码里读到一个硬数字。正常业务一般有裕量;泄漏型 outlier 照样会撞线,而且撞之前用户已经先感到卡了。


第 3 章 Play 2027 门槛:三条指标与分桶规则

Play 的三条线彼此独立:动态内存(Anonymous RSS + Swap)、Bitmap、DEX 优化。任意一条在对应分桶里超 P90,都可能记 bad behavior。2027 年 2 月 1 日起强制执行内存和 DEX 相关项;换机登录单独卡在 2027 年 4 月。

3.1 动态内存:Anonymous RSS + Swap

从加载到运行,贯穿前台、User-perceived services、后台、缓存各状态的私有内存都算(swap 含 zRAM 压缩页)。评估用 90 分位(28 天滚动窗口),按 App / Game、设备 RAM 档位分桶,仅手机/平板。

P90 到底意味着什么? 不是「平均值还行」,而是:28 天内,该分桶里 10% 的最差会话仍然达标。用户群里只要有 10% 的 4 GB 机长时间后台挂着,你的 Background P90 就会被这部分人拉高。开发机跑一夜没事,说明不了什么。

进程状态怎么理解:

状态 大致含义 考核特点
Foreground 用户正在交互的界面 阈值最高,长会话页最容易顶
User-perceived 前台服务、导航、通话等用户可感知后台 介于前台与纯后台之间
Background 不可见但仍运行 阈值紧,泄漏型问题先在这里暴露
Cached 进程在缓存列表 动态内存阈值不单独考核;Bitmap 仍看 400 MB 线

App 分桶(Cached 状态不单独考这条动态内存阈值;0~4 GB、16 GB+ 档暂无考核线):

RAM 档位(Total Memory) Foreground P90 User-perceived Background
4 GB(3200~4800 MB) ≤ 2 GB ≤ 1 GB ≤ 1 GB
6 GB(4800~6800 MB) ≤ 2.25 GB ≤ 1.25 GB ≤ 1.25 GB
8 GB(6800~9216 MB) ≤ 2.25 GB ≤ 1.5 GB ≤ 1.5 GB
12 GB(9216~14336 MB) ≤ 3.25 GB ≤ 1.75 GB ≤ 1.75 GB
16 GB(14336~18432 MB) ≤ 4.25 GB ≤ 2 GB ≤ 2 GB

Game 分桶(同上,Cached 不考动态内存;档位划分与 App 一致):

RAM 档位(Total Memory) Foreground P90 User-perceived Background
4 GB(3200~4800 MB) ≤ 2.25 GB ≤ 2 GB ≤ 2 GB
6 GB(4800~6800 MB) ≤ 2.75 GB ≤ 2.5 GB ≤ 2.5 GB
8 GB(6800~9216 MB) ≤ 3.5 GB ≤ 2.75 GB ≤ 2.75 GB
12 GB(9216~14336 MB) ≤ 4 GB ≤ 3.2 GB ≤ 3.2 GB
16 GB(14336~18432 MB) ≤ 5 GB ≤ 3.5 GB ≤ 3.5 GB

官方按 Play Console 里配置的 App / Game 品类分表,依据是游戏前台长会话、native 引擎占内存的模式与工具类 App 不同。别把品类改成与核心功能不符的类别来蹭 Game 阈值------这违反商店 Metadata 政策。

App 与 Game 前台阈值差距不大,User-perceived / Background 差距才明显。以 8 GB 档为例,Background 上限 App 是 1.5 GB,Game 是 2.75 GB,几乎翻倍:

RAM 档位 App Background Game Background 差额
4 GB 1 GB 2 GB +1 GB
6 GB 1.25 GB 2.5 GB +1.25 GB
8 GB 1.5 GB 2.75 GB +1.25 GB
12 GB 1.75 GB 3.2 GB +1.45 GB
16 GB 2 GB 3.5 GB +1.5 GB

另一点容易忽略:分档用的是设备 Total Memory(系统上报的总内存),可以低于包装盒上的 Physical RAM 标称值。同一款「8 GB 手机」,分桶边界是 6800~9216 MB,别按营销规格自行归类。

别直接套用 App 的数去估游戏包,尤其 hybrid 应用(游戏壳 + 重型社交/商城模块)要按 Console 实际品类看表。

3.2 Bitmap 内存:非前台别长期囤图

Bitmap 只有 UI 可见时才有渲染意义。Vitals 对 User-perceived / Background 的 Bitmap P90 > 200 MB 、Cached > 400 MB 记 bad behavior------App 与 Game 共用同一套 Bitmap 阈值 ,没有 Game 豁免线。阈值不是零,是给 onTrimMemory 留缓冲;卡的是后台长期持有大图,不是短暂过渡状态。

粗算一下就知道 200 MB 有多紧:一张 1080p、ARGB_8888 的全屏图大约 8 MB。后台攥 25 张没释放,就已经踩线。信息流如果按「一屏 10 条、每条 2 张缩略图」缓存,两轮下来就是 160 MB------还没算解码过程中的临时 buffer。

信息流、相册预览、电商详情页这类 App 要特别当心:前台切后台后,列表里的缩略图如果还攥在手里,P90 很容易超。onTrimMemory 写了但图片库没接回调,等于没写。Glide / Coil / Fresco 的 memory cache 策略,建议按 RAM 档分级,别所有机型同一套上限。

3.3 DEX 优化:至少 25%

2027 年 2 月起,非 negligible DEX 要求 shrinking、optimization、obfuscation 各 ≥ 25%

类型 触发条件 三项各自要求
App 未压缩 DEX > 10 MB shrink / optimize / obfuscate 各减 ≥ 25%
Game 未压缩 DEX > 50 MB 同上

R8 或其他 shrinker 都行;App Bundle Explorer 会展示各次上传的优化占比。官方建议 proguard-android-optimize.txt,别在 gradle.properties 里长期关 R8 full mode。

举个数量感:某 App 上传 20 MB 原始 DEX,三项各需至少减掉 5 MB(25%)。如果 shrinking 只少了 3 MB,即使 optimize 和 obfuscate 都达标,照样不过。老项目最怕这条------多年没动 ProGuard 规则,一开 R8 先炸反射调用,再炸第三方 SDK。「开 R8」和「能过 25% 且不上线回归」之间,往往还差一轮规则修补和灰度。


第 4 章 工具链:从 Vitals 到 ProfilingManager

2026 年下半年起,Play Console 配套能力陆续上线:

层级 工具 用途
宏观 Android vitals → Memory RSS+Swap、Bitmap 按 RAM 档与进程状态下钻
终止事件 Crashlytics 20.1.0+、ApplicationExitInfo OOM 与 Memory Limiter 退出上下文
产线剖面 ProfilingManager(API 35+) TRIGGER_TYPE_OOMTRIGGER_TYPE_ANOMALY 触发 heap dump
预警 Vitals 概览页 超 bad behavior 阈值时主动告警
后续 2026 年下半年 各状态停留时长、Memory Limiter 更深诊断(官方预告)

TRIGGER_TYPE_ANOMALY 值得接,但别高估落地速度:要 API 35+,还要处理 dump 上传、存储和隐私合规。它的价值在于系统判定异常(含逼近 memory limit)时,能在强制杀进程前回调------正好补上「无栈终止」的产线盲区。

第一周就能做的三件事

不用一上来就全栈,按这个顺序推进就够起步:

  1. Console 基线(半天):打开 Vitals → Memory,按 4 / 6 / 8 GB 档分别看 Foreground、Background 的 RSS+Swap 和 Bitmap 曲线,记下离阈值最近的一档。
  2. 启动扫退出原因(1~2 天) :主进程启动时读 ApplicationExitInfo,把 MemoryLimiter:AnonSwap 和 OOM 分开上报;先接日志,再接告警。
  3. ADB 压测(1 天) :在 Android 17 测试机用 am memory-limiter 复现 zRAM 阶段的 jank,确认性能团队能在本地看到掉帧,而不是等线上猜。

已有性能观测框架的团队,把 Memory Limiter 信号和 anomaly 触发放进同一 dashboard。还在只靠 Java heap 指标的,建议先把 Vitals Memory 页按 RAM 档拆开看一遍------很多时候问题出在 4 GB 档的 Background 分桶,而不是你手里那台 12 GB 开发机。


第 5 章 换机登录:Zero-Tap Sign-In 与 Restore Credentials

这条跟内存无关,但 deadline 挨得近,最好跟内存排进同一张表:

时间节点 要求
2026-09-30 前 可用 Block Store 恢复登录态,视为过渡期合规
2027-02-01 起 内存 / DEX 相关 bad behavior 强制执行
2027-04-01 起 支持登录的 App 须在 D2D / 云恢复后自动恢复登录态

细则:

  • 标准实现是 Android Restore Credentials API(Credential Manager,Android 9+)。
  • Game 暂豁免正式要求;单账号游戏仍鼓励接入。
  • 金融、医疗等可申请豁免;企业专用设备不在范围。

换机手动登录伤转化,这点不用 Google 说大家也知道。真正麻烦的是存量登录体系:自建 token、多端踢登、风控二次验证,迁到 Restore Credentials 不是改一个 API 就完事。

已有 Credential Manager / passkey 集成的团队,改动量通常在一两个迭代内(Uber 公开案例也在这个量级)。还在用 WebView 登录或老版 AccountManager 封装的,得单独估人天------而且这条线跟内存优化抢的是同一拨 Android 工程师,别假装可以串行排。


第 6 章 生态影响:谁要先动、谁可以缓一缓

优先排期的,通常是这几类:

  • 信息流、相册、短视频:后台 Bitmap 和 Anonymous RSS 最容易顶线;4 GB 用户占比每多 5 个百分点,Background P90 的压力就明显上一档。
  • 长会话游戏、直播类:Game 动态内存阈值虽高(8 GB 档前台 3.5 GB、Background 2.75 GB),但 native 堆、纹理、音视频 buffer 叠加后峰值照样可观;Bitmap 仍卡 200 MB / 400 MB,与 App 相同;DEX 触发线 50 MB 也比 App 的 10 MB 严得多。
  • DEX 体积大、多年没开 R8 的包:10 MB / 50 MB 是硬触发线,不是建议值。
  • 有登录、没做换机恢复的社交、工具、金融 App:2027-04 是硬线,而且跟内存无关,最容易被排期表漏掉。

相对省事的,多半是已经用 Vitals 管过 ANR/崩溃、R8 在跑、onTrimMemory 有实际释放逻辑的中型 App。补监测、补压测、对照 Console 分桶看一圈,通常一两周内能摸清差距在哪。无登录 App,或纯 Game(只看 Zero-Tap 这一条),短期内压力确实小一些。

OEM / 渠道侧,Memory Limiter 往多厂商、多 RAM 档扩,「高端机无限堆内存」的产品假设在系统层站不住;Play 阈值是同一方向的另一刀。媒体有时把移动内存收紧和数据中心 DRAM 争用放在一起聊,那是宏观叙事;你排期时还是以 Console 里的分桶数据和自家 Vitals 曲线为准,别被二手解读带着走。


结论与建议

2026 下半年起,应用内存从「最佳实践」变成硬约束:系统 enforcement 管会话级 outlier,商店 enforcement 管 28 天人口级坏行为,换机登录是并行的第三条合规线。三条线互不替代,漏任何一条都会在另一个维度挨打。

时间 动作
现在~2026 Q4 Vitals Memory 基线;启动读 ApplicationExitInfoadb memory-limiter 压测
2027-02 前 Anonymous RSS+Swap / Bitmap P90 达标;DEX 三指标各 ≥ 25%
2027-04 前 Restore Credentials 或 Block Store(过渡期)换机登录
持续 onTrimMemory、图片库 cache 按设备分级、Profiler + TRIGGER_TYPE_ANOMALY

最后留三个排障时真用得上的判断:

Memory Limiter 杀进程不一定有 crash 栈,得接 MemoryLimiter:AnonSwap。Play 看 P90 分桶,开发机过关不算数,先看 4 GB 档 Background。内存和换机登录两条 deadline 别分开排------见过太多团队 Q1 赶完内存,Q2 才发现登录恢复没排上人,发布窗口直接卡死。

如果你现在只能做一件事:打开 Vitals Memory,找到离阈值最近的那个 RAM 档和进程状态组合,那就是你接下来两个月最该砸时间的点。


相关推荐

Play Console 技术质量要求(Google Help,2026-08-26) --- 内存 P90 阈值、DEX 优化占比、Zero-Tap Sign-In 等完整细则与合规日历。

reverse-skill 给 AI Agent 装上逆向与渗透的路由大脑

相关推荐
海兰33 分钟前
【 Python 量化交易】第10章:八大经典策略
android·python·kotlin
Rytter37 分钟前
Android诈骗裸聊软件逆向分析
android
JMchen1231 小时前
【Android 性能优化实战 60 讲】04 Memory Profiler 高阶玩法:深剖堆内存原理,实战定位 Kotlin 闭包隐式泄漏
android·性能优化·kotlin·实战·源码分析·内存泄漏·memory profiler
Android-Flutter1 小时前
Java线程池 - 内部线程管理机制详解
android
开开心心就好1 小时前
手机悬屏翻译工具外语游戏漫画APP全覆盖
android·前端·javascript·python·游戏·pdf·html
恋猫de小郭2 小时前
AI 时代,也许你的 Flutter 需要一套 Dartastic OpenTelemetry 监控
android·前端·flutter
Kapaseker2 小时前
我为什么喜欢 Compose ?
android·kotlin
JMchen1232 小时前
【Android 性能优化实战 60 讲】03 Perfetto 现代分析利器:SQL 查询 Trace 数据,微秒级定位函数 CPU 耗时
android·sql·性能优化·实战·源码分析·perfetto·启动优化
开开心心就好3 小时前
手机精确倒计时工具悬浮窗口秒数实时显示
android·前端·javascript·jupyter·智能手机·pdf·html