支持 16 KB 的页面大小  |  Compatibility  |  Android Developers

在 Android 15 及即将到来的 Android 16 中,Google 引入了一个重大的底层变化:支持 16KB 页面大小(Page Size)

过去 15 年,Android 一直假设内存页大小恒定为 4KB。随着硬件内存容量的增加,切换到 16KB 页面可以将系统性能提升 5%~10%,但这对包含 原生代码 (C/C++) 的应用来说是一个巨大的挑战。


1. 为什么要适配?

如果你的应用包含原生代码(通过 NDK 开发),而这些代码是针对 4KB 页面编译的,那么在 16KB 模式的设备上,应用会直接 Crash(崩溃)

  • 受影响的应用: 包含 .so 文件(原生库)、使用某些底层内存分配算法、或者集成了第三方 SDK(如地图、游戏引擎、加固工具)的应用。

  • 不受影响的应用: 纯 Java/Kotlin 开发、且未集成任何包含 jni 代码库的应用。


2. 核心适配步骤

第一步:重新编译原生代码 (NDK)

你需要更新 NDK 版本(建议使用 r27 及以上),并修改编译标志,确保生成的 ELF 文件符合 16KB 对齐要求。

在你的 Android.mkCMakeLists.txt 中,需要确保链接器使用了 -z max-page-size=16384 标志。

  • AGP 8.3 及以上版本:build.gradle 中可以更简单地开启:

第二步:代码中的硬编码检查

搜索 C/C++ 代码中所有硬编码为 4096PAGE_SIZE 的地方。

  • 错误写法: int bufferSize = 4096;

  • 正确写法: 使用 sysconf(_SC_PAGESIZE)getpagesize() 在运行时动态获取页面大小。

第三步:验证对齐

你可以使用 SDK 提供的工具检查你的 .so 文件是否已经正确对齐:

如果显示的 Alignment 数值是 0x4000 (16384),说明对齐成功;如果是 0x1000 (4096),则仍需重新编译。


3. 如何测试?

为了测试应用在 16KB 环境下的稳定性,Google 提供了专门的模拟器镜像。

  1. 下载镜像: 在 Android Studio SDK Manager 中,查找 Android 15 (VanillaIceCream) 下带 "16k page size" 标签的模拟器系统镜像。

  2. 运行应用: 将你的应用安装到该模拟器。

  3. 观察现象: 如果应用启动即闪退,且 Logcat 报错类似 segment alignment,说明适配未完成。


4. 适配 16KB 对持久化方案的影响

既然你之前关注 MMKV,这里有一个关键点:

  • MMKV 高度依赖 mmap: mmap 操作通常是按页面大小进行的。

  • 潜在风险: 如果 MMKV 的底层逻辑硬编码了 4KB 对齐,或者在创建文件时没有按照 16KB 步进,可能会导致在 Android 16 模拟器上出现读写异常。

  • 解决方案: 确保更新到 MMKV 的最新版本,腾讯团队已经在近期版本中针对 16KB 页面做了兼容性补丁。


总结:

  1. 更新 NDK 至最新版。

  2. 链接器标志:增加 -Wl,-z,max-page-size=16384

  3. 动态获取页大小:替换代码中的 4096

  4. 三方库更新:检查你使用的所有三方 SDK(如微信支付、高德地图)是否已发布 16KB 兼容版本。