Android 15 适配之16K Page Size :为什么它会是最坑的一个适配点

news2024/9/22 7:22:04

首先什么是 Page Size ?一般意义上,页面(Page)指的就是 Linux 虚拟内存管理中使用的最小数据单位,页面大小(Page Size)就是虚拟地址空间中的页面大小, Linux 中进程的虚拟地址空间是由固定大小的页面组成。

Page Size

对于虚拟内存, CPU 的内存管理单元(MMU)会将虚拟地址转换为物理地址,所以虚拟内存最终也会映射到物理内存页面。

而为了实现虚拟内存到物理的映射,两个地址空间都会被划分为多个固定页面,而虚拟空间和物理空间中的页面需要大小相同,通常长度为 4K,为了区分虚拟页面和物理页面,后者一般会被称为页框(page frames )。

就是每个应用都有自己独特的虚拟地址空间,并且它永远也不要关心其他应用在做什么,占据了哪些真实地址,实际物理地址映射,是由 Linux 内核去管理和分配,虚拟内存也是为什么系统支持多应用同时运行的基础

剩下的就很简单了,因为 Android 用的是 Linux 内核,所以在这部分逻辑一直以来都是遵循 Linux 的实现,只是 Android 由于「历史因素」限制,一直只支持 4 KB 内存页面大小,而现在为了优化系统内存性能,提高内存密集型工作负载的性能,Android 15 开始将采用 16KB 页面大小的要求。

那前面说了那么多「无用的知识」,核心还是 Android 15 要启动 16K Page Size 了,对于我们来说有什么影响?

先说理论上的正面影响:

  • 系统面临内存压力时缩短应用启动时间:平均缩短 3.16%,某些应用的改进甚至高达 30%
  • 降低应用启动时的耗电量:平均减少 4.56%
  • 相机启动速度更快:热启动速度平均加快 4.48%,冷启动速度平均加快 6.60%
  • 改善系统启动时间:平均改善1.5%(约0.8秒)

那么负面影响是什么?你带有 .so 的 android 项目,很可能需要重新编译带有全新的动态库(.so) 才能正常运行对应功能,不然大概率会 crash

至于你的项目里有没有动态库,相信你应该很清楚,如果不清楚,直接把 apk 拖到 Android Studio ,看看 lib 下是否有 so 文件即可。

那为什么说用 Android 15 启动 16K Page Size 后,以往使用了 C/C++(native)代码的基本都会 crash 呢?这就是前面说到的 Linux 下 Page Size 的实现

可能大家会觉得,为什么不能有兼容层,将 4k 页面大小转换为 16k 页面大小?

理论上这是可行的,比如你可以使用虚拟化技术让 4K 的应用跑在 16K 主机上,但是想要系统直接混搭 Page Size 支持,是一个比较困难的事情。

前面我们知道,虚拟内存和物理内存之间存在映射,那么如果 CPU 处于 16K 模式,那么其实所有内容都会处于 16K 模式,简单不严谨的理解,这会是一个 CPU 全局寄存器设置的概念。

所以对于所有空间页面而言,在任意时刻要么是 4K,要么是 16K页表结构在 4K 模式和 16K 模式下完全不同(每级页面、级数、屏蔽)。

这里扯一段额外的东西, Apple Silicon 的 MacOS 其实是有混合 16K/4K 支持,事实上 macOS 本身始终以 16K 页面运行,只有 Rosetta 模式下应用会以 4K 模式运行:

我大概记得好像是,在 macOS 上,Rosetta 模式用户空间和内核空间的页面大小可以不同,不同的用户空间程序可以使用不同的页面大小运行。

因为 Linux 不支持混合 Page Size,默认上 android 也不支持,除非 Android OS 层后续也做类似 Rosetta 等处理

如何检测

前面讲了那么多废话,大家肯定还是很关系,如何知道我的 App 是否支持 16K Page Size 运行。

虽然带有陈年 .so 的很大概率不行,但是也许呢?

最简单且最实用的做法就是通过模拟器 VanillaIceCream 的 APIs Experimental 16k Page Size ARM 64 v8a System Image 进行测试。

根据自己的设备,如上图选择下载一个 VanillaIceCream 的 16k Page Size 的模拟器镜像,然后在 Other Images 选择下载的镜像创建模拟器。

注意,这里干活来咯,因为老板本 AS 在 LLDB 调试 16 KB 模拟器系统映像会存在问题,所以至少需要下载一个和 Android Studio Koala Feature Drop | 2024.1.2 Canary 5 ,就是如下图所示这个,带 Drop 版本的才能成功运行 16K Page Size 模拟器。

什么是 Drop 版本?可以参考:https://juejin.cn/post/7379816515551723546

运行模拟器之后,通过 adb shell getconf PAGE_SIZE 可以获取到一个 16384 的值,说明系统现在已经是 16K 的模式。

那么,我把 GSYVideoPlayer 运行到 16K 模拟器后,不出所料 IJK 内核无法正常播放。

另外,官方提供了一个 16 KB ELF 对齐脚本来验证共享库的 ELF 段是否正确对齐,如下脚本针对 GSYVideoPlayer 里的动态库进行校验后,输出却是比较意外。

#!/bin/bash

# usage: alignment.sh path to search for *.so files

dir="$1"

RED="\e[31m"
GREEN="\e[32m"
ENDCOLOR="\e[0m"

matches="$(find $dir -name "*.so" -type f)"
IFS=$'\n'
for match in $matches; do
  res="$(objdump -p ${match} | grep LOAD | awk '{ print $NF }' | head -1)"
  if [[ $res =~ "2**14" ]] || [[ $res =~ "2**16" ]]; then
    echo -e "${match}: ${GREEN}ALIGNED${ENDCOLOR} ($res)"
  else
    echo -e "${match}: ${RED}UNALIGNED${ENDCOLOR} ($res)"
  fi
done

可以看到此时动态库是 ALIGNED 的,并且是 2**16 ,也就是 armv68a 的动态库此时的 ELF 对齐。

另外,通过 sdk 的 build-tools/35.0.0 下的 zipalign 命令运行:

./zipalign -c -P 16 -v 4 /Users/guoshuyu/workspace/android/GSYVideoPlayer/app/build/outputs/apk/release/app-release.apk

可以看到此时的 apk 对齐也是没有问题的,所以此时的运行问题可能更多在于 C++ 代码里的 mmap 或者 sysconf 等代码存在问题,例如写死了 4096 等硬编码。

兼容

对于 LLDB 调试 16 KB 模拟器,需要 NDK r27 RC 1 的支持, 如果使用 r27 及以上的版本,那么只需要在 Application.mk 配置:

APP_SUPPORT_FLEXIBLE_PAGE_SIZES := true

如果是 Android NDK r26 及更低版本 ,则需要在 Android.mk 启用 16 KB ELF 对齐 :

LOCAL_LDFLAGS += "-Wl,-z,max-page-size=16384"

另外,构建支持 16 KB 设备的应用还需要 AGP 8.3 + 的支持,16 K 设备会要求附带未压缩共享库的应用将它们对齐到 16 KB 压缩对齐,为此升级到 Android Gradle 插件 (AGP) 版本 8.3+ 会是一个比较好的选择。

如果使用 AGP 版本 8.2或更低的版本,那么另一种选择是切换到使用压缩共享库

如果您无法将 AGP 升级到 8.3 或更高版本,那么另一种选择是切换到使用压缩共享库:

android {
  ...
  packagingOptions {
      jniLibs {
        useLegacyPackaging true
      }
  }
}

也就是什么?适配的基础是重新编译 .so ,重新编译的基础是:

  • NDK r27 推荐,NDK r26 及更低版本可以修改 max-page-size ,当然太低是真不行,反正目前测试我的 NDK r10e 是有问额····
  • AGP 8.3 + 推荐,低版本可以用 useLegacyPackaging

当然,重新编译只是基础,代码里使用了例如 mmap 或者硬编码 4096 的地方,都需要修改适配

那么问题来了,老旧 .so 连源码都没有的情况下,是不是没救了? 答案是肯定的,确实没救了,更糟心的是:谷歌计划明年将对 16k 设备的支持作为 Google Play 应用程序提交的必要条件

本质上你的 .so 可能已经是 16K 对齐,但是还存在逻辑适配问题。

所以逃是逃不开了,好消息是目前这是一个实验性的阶段,另一个好消息,那就是 Flutter 本身已经支持了 16k ,在测试里 Flutter 3.22 是可以在 16K 模拟器上正常运行,这一定程度也算不幸中的万幸了。

最后

所以心凉了没?从目前看,基于 Linux 内核下的 16K Page Size 很大可能不支持 4K Page Size 的 C/C++ native 代码,所以可以遇见的情况有这么几种:

  • Android OS 最终落地了混合 Page Size 支持
  • 重新编译和修改 .so 支持 16K

所以大家觉得会是怎么样的一个结果?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1906987.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何把harmonos项目修改为openharmony项目

一开始分不清harmonyos和openharmony,在harmonyos直接下载的开发软件,后面发现不对劲,打脑阔 首先你要安装对应版本的开发软件,鸿蒙开发是由harmonyos和openharmony官网两个的,找到对应的地方下载对应版本的开发软件&…

rocketmq实现限流

目录 问题背景 技术方向 方案确认 消息队列(√) 分布式锁() 方案实现 监控方向 业务方向 问题背景 公司邮件服务token有 分钟内超200封的熔断机制,当前token被熔断后,系统发邮件操作会被忽略&…

关于微信支付-商户平台:查询订单提示“查询失败:操作失败,请稍候重试”的分析

目录 引子 分析 应对 小结 引子 在开发和实施微信 JSAPI 支付的应用后,我们遇到了一些问题,订单的状态更新不正常,当然我们首先需要从自身寻找原因和完善解决问题的办法和方案。在支付的过程中,客户会给我们一些反馈&#xf…

K8S篇之Ingress详解以及用法说明

一、Ingress简介 Ingress 是 Kubernetes 中用于管理和配置从集群外部访问集群内部服务的资源对象。它通过定义路由规则来控制外部流量的访问方式,支持基于 HTTP 和 HTTPS 的高级路由功能和安全性配置。 Ingress是一种HTTP方式的路由转发机制,为K8S服务配…

【力扣高频题】014.最长公共前缀

经常刷算法题的小伙伴对于 “最长”,“公共” 两个词一定不陌生。与此相关的算法题目实在是太多了 !!! 之前的 「动态规划」 专题系列文章中就曾讲解过两道相关的题目:最长公共子序列 和 最长回文子序列 。 关注公众…

SpringCloud 负载均衡

目录 一、负载均衡 1、问题 2、什么是负载均衡 服务端负载均衡 客户端负载均衡 二、Spring Cloud LoadBalance 1、使用 Spring Cloud LoadBalance 2、负载均衡策略 3、LoadBalancer 原理 一、负载均衡 1、问题 我们来看一下前面写的代码&#xff1a; List<Serv…

【易捷海购-注册安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

Drools开源业务规则引擎(五)- jBPM流程图元素介绍

文章目录 Drools开源业务规则引擎&#xff08;五&#xff09;- jBPM流程图元素介绍1.process2.startEvent3.Connections3.1.sequenceFlow3.2.Association 4.Activities4.1.businessRuleTask4.2.scriptTask 5.Gateways5.1.exclusiveGateway 6.endEvent Drools开源业务规则引擎&a…

Windows netstat命令详解,Windows查看网络连接

「作者简介」&#xff1a;冬奥会网络安全中国代表队&#xff0c;CSDN Top100&#xff0c;就职奇安信多年&#xff0c;以实战工作为基础著作 《网络安全自学教程》&#xff0c;适合基础薄弱的同学系统化的学习网络安全&#xff0c;用最短的时间掌握最核心的技术。 netstat 常用来…

支持图片识别语音输入的LobeChat保姆级本地部署流程

文章目录 前言1. LobeChat对我们有哪些帮助?2. 本地安装LobeChat3. 如何使用LobeChat工具4. 安装Cpolar内网穿透5. 实现公网访问LobeChat6. 固定LobeChat公网地址 前言 本文主要介绍如何在Windows系统电脑本地部署LobeChat&#xff0c;一款高颜值的开源AI大模型智能应用&…

【删库跑路】一次删除pip下载的所有第三方库方法

进入命令行&#xff0c;先list看下库存 pip list导出所有的第三方库至一文件列表 pip freeze >requirements.txt按照列表卸载所有库 pip uninstall -r requirements.txt -y再list看下&#xff0c;可见库存已清空

MATLAB基础应用精讲-【数模应用】 岭回归(Ridge)(附MATLAB、python和R语言代码实现)

目录 前言 算法原理 数学模型 Ridge 回归的估计量 Ridge 回归与标准多元线性回归的比较 3. Ridge 参数的选择 算法步骤 SPSSPRO 1、作用 2、输入输出描述 3、案例示例 4、案例数据 5、案例操作 6、输出结果分析 7、注意事项 8、模型理论 SPSSAU 岭回归分析案…

第三届机器学习、云计算与智能挖掘国际会议(MLCCIM 2024)

随着科技的不断进步&#xff0c;机器学习和挖掘技术已成为推动现代社会发展的重要力量。本届机器学习、云计算与智能挖掘国际会议&#xff08;MLCCIM&#xff09;将于2024年8月8日至8月11日在中国湖北省神农架盛大召开&#xff0c;旨在汇聚全球智慧&#xff0c;共同探讨这一领域…

Linux安装elasticsearch单机版

一、检查内核 uname -a uname -m 二、下载版本 下载版本选择自己服务器相同的内核版本 我这边是aaech64 ES下载地址 Kibana 下载地址 二、上传服务器解压 tar -xvf elasticsearch-8.14.1-linux-aarch64.tar.gz 三、安装ES 因为ES不能用root用户启动先创建用户 #新增 es …

[python]Markdown图片引用格式批处理桌面应用程序

需求 使用python编写一个exe&#xff0c;实现批量修改图片引用&#xff0c;将修改后的文件生成为 文件名_blog.md。有一个编辑框&#xff0c;允许接收拖动过来md文件&#xff0c;拖入文件时获取文件路径&#xff0c;有一个编辑框编辑修改后的文件的输出路径&#xff0c;用户拖入…

抖音商城自定义小程序源码系统 前后端分离 带完整的源代码包以及搭建教程

系统概述 在当今数字化时代&#xff0c;电商平台的便捷性和个性化体验成为了吸引用户的关键。随着短视频平台的兴起&#xff0c;抖音作为其中的佼佼者&#xff0c;其商城小程序成为了商家连接消费者的新阵地。为了帮助商家快速构建个性化、高效的小程序店铺&#xff0c;本文将…

Java面试题--JVM大厂篇之深入探讨Serial GC的应用场景

目录 引言: 正文: 一、什么是Serial GC&#xff1f; 二、Serial GC的工作原理 三、适用场景 单处理器环境在单处理器环境下&#xff0c;Serial GC是一个非常好的选择。由于没有多余的处理器资源&#xff0c;单线程的垃圾回收操作不会导致额外的上下文切换开销&#xff0c…

springboot非物质文化遗产管理系统-计算机毕业设计源码16087

目录 摘要 1 绪论 1.1 选题背景与意义 1.2国内外研究现状 1.3论文结构与章节安排 2系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1系统开发流程 2.2.2 用户登录流程 2.2.3 系统操作流程 2.2.4 添加信息流程 2.2.5 修改信息流程 2.2.6 删除信息流程 2.3 系统功能…

欧拉系统(openEuler) aarch64虚拟机安装

文章目录 一、操作背景二、资源准备三、文件路径四、安装QEMU五、创建磁盘文件六、安装虚拟机七、连接虚拟机八、启动虚拟机 一、操作背景 客户公司扫描出欧拉系统aarch64架构服务器存在编号 CVE-2024-1086 的内核漏洞&#xff0c;需要对内核升级&#xff0c;首先在个人电脑虚…

硬盘错误0x80071ac3如何修复?5大免费修复法,轻松找回硬盘数据

今天我们要聊的是一个让大家头疼不已的问题——硬盘错误0x80071ac3。你是否也曾经遇到过这个烦人的错误代码&#xff0c;导致数据无法读取、文件丢失&#xff0c;甚至整个硬盘都无法正常使用&#xff1f;别担心今天小编就为大家详细解析这个错误的原因&#xff0c;并分享5个免费…