通过安装包重排布优化 Android 端启动性能

  • 时间:
  • 浏览:0
  • 来源:5分6合APP下载_5分6合APP官方

final String file = value.string.toString();

刷入 ROM,替换修改后 framework 后,冷启动支付宝,清楚缓存,通过日志过滤即可得到完整篇 启动文件加载列表。

* Loads an XML parser for the specified file.

调整前

echo 1 > /proc/sys/vm/drop_caches

原本的度量方案,具备较深的技术含量,在本身方案中,无需 对 Linux 底层文件系统都可以 无需 熟悉和了解,有后后还需具备修改源码的能力,此方案是由许多资深专家指导下实现,短期内,团队暂时无法独立本身方案。

为了让整体方案可控,大伙儿儿想到了直接在 Android 源码的资源加载流程中记录日志,有后后通过日志直接分析,原本启动阶段文件加载一目了然,当然匮乏也很明显,无法通过判断文件读取是通过磁盘 IO 还是 pagecache 缓存。

干预资源加载记录,要不通过 hook 辦法 ,要不好多好多 直接改 framework,刷个 ROM,考虑到工程化自动化测试的因素,采用了修改 framework 的辦法 ,方便后续有测试平台,直接使用特定手机跑脚本执行即可。

以 Android 7.0 版本为例,主要修改 drawable 相关流程和 xml 相关流程。许多版本不可能 做测试度量机型的化,修改辦法 累似 。

// First see if this block is in our cache.



if (name != null) {

if (!getResourcePackageName(id).equalsIgnoreCase("android")) {

}

Two-List 策略维护了4个多list,active list 和 inactive list。在 active list 上的 page 被认为是 hot 的,都可以 释放。都可以 无需 inactive list 上的 page 无需 被释放的。首次缓存的数据的 page 会被加入到 inactive list 中,不可能 在 inactive list 中的 page 不可能 再次被访问,就会移入 active list 中。4个多链表都使用了伪 LRU 算法维护,新的 page 从尾部加入,移除时从头部移除,就像队列一样。

5. 演进

* @param id the resource identifier for the file



}

 ●  线下使用工具度量 IO 情況,观察启动阶段磁盘 IO 数量否有减少,量化4个多“cache miss 率”的概念。 ●  线下通过收集的方案,通过脚本,多次模拟冷启动,取平均值测量,消除不可能 误差,观察趋势。

 ●  线上灰度在许多优化和代码累似 情況下,只通过调整 IO,比较4个多版本的启动时间变化。 在重布局方案实验阶段,使用一二本身方案较多,后续工程化落地和常态化优化时,应采用三本身方案。

+ Integer.toHexString(id) + ") is not a Drawable (color or path): " + value);

* @param type the type of resource (used for logging)

}

Resources.Theme theme) {

}

}

有后后内核将读取的数据缓存到 cache 中,原本后续的读请求就无需 命中 cache 了。Page 无需 只缓存4个多文件帕累托图的内容,不无需 把整个文件都缓存进来。对磁盘的数据进行缓存从而提高性能主好多好多 基于4个多因素:

4. 落地方案

final XmlBlock[] cachedXmlBlocks = mCachedXmlBlocks;

if (value.string == null) {

if (cachedXmlBlockCookies[i] == assetCookie && cachedXmlBlockFiles[i] != null

* Loads a drawable from XML or resources stream.

第一列表示指在 IO 的位置,不可能 为 0,则表示指在了真实的磁盘 IO;不可能 为 1,则表示从pagecache 缓存中读取了内容。



}

原文发布时间为:2018-11-29

Log.i("AlipayRes", "ResourceId: " + Integer.toHexString(id) + " ResourcePackage name: " + getResourcePackageName(id) + " Loading drawable: " + file);

* @param assetCookie the asset cookie for the file

return cachedXmlBlocks[i].newParser();

如下图所示,Linux 底层文件系统中 VFS 上次 App 应用程序之间,指在一层 pagecache,pagecache 由内存中的物理 page 组成,其内容对应磁盘上的 block。Pagecache 的大小是动态变化的,无需 扩大,本来需要 在内存匮乏时缩小。Cache 缓存的存储设备被称为后备存储(backing store),4个多 page 通常中有 多个 block,有有哪些 block 不一定是连续的。

private Drawable loadDrawableForCookie(Resources wrapper, TypedValue value, int id,

@NonNull String type)

throw new NotFoundException("Resource \"" + getResourceName(id) + "\" ("

通过上述落地方案,在线下以及许多线上灰度版本中完成初步实验后,大伙儿儿考虑工程化,常态化的进行这件事情。在工程化完后 ,先对度量流程进行了扩充,探索出了本身较为简单的度量手段。

* @throws NotFoundException if the file could not be loaded

if (DEBUG_LOAD) {

}

本节将主要记录通过对支付宝 Android Apk 文件的重新布局,来改善 IO 性能的过程。

/**

Log.v(TAG, "Loading drawable for cookie " + value.assetCookie + ": " + file);

adb shell am force-stop com.eg.android.AlipayGphone

有后后通过解析结果和先前的统计结果对应分析,就能找到 zip 中有 哪些文件,在启动阶段被读到,为重布局提供数据支撑。

……

 ●  工程化:

好多好多 有单点能力都基本具备单点能力都具备后,无需 找到4个多能尽不可能 自动化的方案。具体流程图如下。

后续对于 ReApk (优化Apk)流程,无需 扩展许多的构建构建产物优化方案。

@NonNull

Facebook 的工具链优化方案 Redex,对于 dex 的优化,从度量到回归测试,开源出了一整套外理方案,对于 zip 的重布局,希望未来能将此整套方案,做到尽不可能 的“开箱即用”,赋能公司内外更多的 App。

3. 原理

不可能 active list 中 page 的数量远大于 inactive list,这麼 active list 头部的页面会被移入 inactive list 中,从而维持4个多表的平衡。简单的说,通过文件重布局的目的,好多好多 将启动阶段无需 用到的文件在 APK 文件中排布在同时,尽不可能 的利用 pagecache 机制,用最少的磁盘 IO 次数,读取尽不可能 多的启动阶段无需 的文件,减少 IO 开销,从而达到提升启动性能的目的。

Log.i("AlipayRes", "ResourceId: " + Integer.toHexString(id) + " ResourcePackage name: " + getResourcePackageName(id) + " Loading xml: " + file);

}

&& cachedXmlBlockFiles[i].equals(file)) {

……

if (!getResourcePackageName(id).equalsIgnoreCase("android")) {

7z a -tzip archive.zip source* ^list.txt

if (id != 0) {

通过本身辦法 ,就实现了文件重排布的简单过程,当然在支付宝的构建流程中,较为繁杂,里边还涉及到重打包,重签名等一系列流程。后续内容会提到。

这里有4个多小插曲,在刚结速调整文件顺序时,大伙儿儿通过测量发现效果并不好。然后发现了由于,原本大伙儿儿调整的文件列表,好多好多 度量阶段发现,所有指在磁盘 IO 的文件,把大伙儿排布到同时,错误的认为,假使 大伙儿调整了,整体 IO 情況就会改善。原本忽略了“此消彼长”的大间题,不可能 只调整有有哪些文件,这麼 原本排布在有有哪些文件里边,利用预读机制进缓存 cache 的文件,不可能 在启动阶段用到,不可能 会指在新的磁盘 IO。正确的调整辦法 ,应该能精确按时间顺序统计启动阶段的所有文件,排布在同时,原本指在一定量 IO,就能完整篇 读到 cache 中。

简单看下某一次实验主 Apk 中文件调整前后的效果如下,几块和配置相关的移到文件头部。

布局前后,Apk 中实际的文件并这麼 本质改变,都可以 无需 位置指在了变化。这麼 为有哪些原本的调整会有性能造成影响?本身原理要追溯到 Linux 的文件系统机制。

final int num = cachedXmlBlockFiles.length;

final String name = getResourceName(id);

 ●  第二是被访问过的数据,有很最少率会被再次访问。

结合 Android 系统实际来看,上层 App 每次读取磁盘时,文件系统默认会按 16 * 4k block 去磁盘读取数据,并把数据装下 pagecache 中。不可能 下次读取文件不可能 在 pagecache 中,则无需指在真实的磁盘 IO,好多好多 直接从 pagecache中 读取,大大提升读的速率。有缓存全是回收,pagecache 的原本重要工作是释放 page,从而释放内存空间。Cache 回收的任务是取舍最少的 page 释放,有后后不可能 page 是 dirty 的,无需 将 page 写回到磁盘中再释放。

*/

……

}

当内核发起4个多读请求时(累似 应用程序发起 read() 请求),首先会检查请求的数据否有缓存到了 pagecache 中。不可能 有,这麼 直接从内存中读取,不无需 访问磁盘,这被称为 cache命中(cache hit)。不可能 cache 中这麼 请求的数据,即 cache 未命中(cache miss),就无需 从磁盘中读取数据。

final String[] cachedXmlBlockFiles = mCachedXmlBlockFiles;

/**

XmlResourceParser loadXmlResourceParser(@NonNull String file, @AnyRes int id, int assetCookie,

// Log only framework resources

支付宝 App 在 Android 平台上,不可能 一定量业务快速上线,Android 长尾机型等由于,造成启动阶段及帕累托图核心链路上,性能体验不理想,进而影响用户的使用的感受。

从纯业务层厚,无需 通过优化 UI 布局,优化代码形态学 ,优化 bundle 加载等辦法 ,对性能体验有所改善。作为工程技术团队,按照传统思维来看,似乎无法对性能优化做几块贡献。经过许多方案调研后,大伙儿儿尝试通过对编译产物的优化,干预构建流程,以提升 App 性能。

if (TRACE_FOR_MISS_PRELOAD) {

数据中,第一列的数据表示指在 IO 行为的文件,第二列表示该文件中此偏移量对应的部收集生了 IO 行为。

* @return a parser for the specified XML file

throws NotFoundException {

……

按照好多好多 有计划将文件完整篇 调整完毕后,就到了验证效果的环节。主要有以下几种验证辦法 和思路:

try {

理想的做法是释放距离下次访问时间最久的 page,有后后很明显,这是不现实的。基于 LRU改进的 Two-List 是 Linux 使用的策略。本身回收策略非常累似 业务开发领域,常见的图片加载的缓存策略。LRU 算法是取舍最近一次访问时间最靠前的 page,即干掉最近没被光顾过的 page。原始 LRU 算法指在的大间题是,许多文件只会被访问一次,有后后按照 LRU 的算法,即使有有哪些文件完后 再好多好多 会被访问了,有后后不可能 它们是完后 被访问的,就无需被选中。

for (int i = 0; i < num; i++) {

drawable 修改

目前整体方案,已上线支付宝钱包 Android App,该单项,启动性能,在整体全量用户下有 5% 左右的优化效果,低端机上效果较明显,根据不同机型,能有10%左右的启动性能优化效果。

本章节大伙儿儿将围绕《支付宝 App 构建优化解析》另启新系列,细分拆解客户端在“代码管理”、“证书管理”、“版本管理”、“构建打包”等维度的具体实现方案展开讨论,带领大伙儿儿进一步了解支付宝在 App 构建模块下的持续优化。

2. 背景

Log.d(TAG, "Loading framework drawable #" + Integer.toHexString(id)

+ ": " + name + " at " + file);

调整后

if ((id >>> 24) == 0x1) {



}

在得到4个多启动阶段的文件列表后,第二步工作,好多好多 根据本身文件列表,在构建打包阶段,在 Apk 中把这帕累托图文件排布在同时。这里无需 修改 7z 压缩工具的源码。支付宝构建流程,为了提升压缩速率,减少包大小,使用 7z 工具进行最后压缩出 Apk 的过程。这里在简单阐述下,重排布的由于,无论是那种压缩工具,zip 中文件顺序是文件系统的默认顺序,即按照阿拉伯数字和字母顺序。不可能 想指定文件排在同时,必然要打破本身规则。

修改 7z 源码的过程,简单思路如下,扩展4个多命令行参数,大伙儿儿使用了上箭头'^'(表意性强,提前的意思),无需 传入 list.txt,有后后 7z 执行输出文件流完后 ,按照 list 中的文件顺序,改变最后的输出顺序,从而达到重排布的目的。累似 如下命令,好多好多 将 source 目录中,所有文件压缩,有后后把 list 中指定文件排布在 zip 包的结速位置。

通过数据无需 发现,Apk 中帕累托图文件,实际上是指在了磁盘 IO,无需 尝试将启动阶段, Apk 中所用到的文件排布到同时,期望通过一定量的 IO,就将所有的文件完整篇 读到。完后 的工作,无需 通过解析 zip 包形态学 ,将上述结果中,文件偏移量对应到完整篇 的文件名。首先无需 得到安装包中的文件排布情況,无需 通过累似 010 Editor 的工具得到,为了工程化的考虑,本来需要 参考 zip 格式定义通过脚本分析 zip 文件实现。

本文来自云栖社区媒体协作伙伴“安卓巴士Android开发者门户”,了解相关信息无需 关注“安卓巴士Android开发者门户”。

adb shell

重布局的前提无需 是精确的度量,定位到有有哪些无需 调整,无需 调整的文件。本身过程无需 足够的准确,有后后会由于重布局完后 的效果不佳。

度量的最终目的是要,统计到支付宝启动阶段,有哪些文件加载了,有后后是指在真实的磁盘IO,还是命中了 pagecache 缓存。大伙儿儿提供了4个多度量工具,通过修改 kernel 源码,dump 出文件系统的 IO 行为,在特定的 Android ROM 上打个补丁,用来统计启动时刻文件行为。帕累托图数据如下:

1. 前言

synchronized (mCachedXmlBlocks) {

* @param file the path for the XML file to parse

}

*

在了解原理完后 ,就无需 考虑为什么会么会用工程化的方案在支付宝 App 上落地,主要从以下4个多流程来设计方案并落地。

final int[] cachedXmlBlockCookies = mCachedXmlBlockCookies;

*/

本文作者:瑞涵



猜你喜欢

巴金的《家》、雨果的《巴黎圣母院》、狄更斯的《大卫·科波菲尔》这三篇的故事梗概

 我来答下载百度知道APP,抢鲜体验也,不老实。着实我也想抄。换一换展开删剪不得劲推荐你对你你这名 回答的评价是?晕,还用得着提问嘛?直接搜索已处置的不就行了不使用百度知

2020-02-22

Docker学习之路(三)

要删除详细image句子下载jdk、tomcat安装包,上传/usr/local/soft目录下FROM:指定基础镜像,因此时需是第根小指令因此重启docker服务ADD:群克

2020-02-22

与webshell后门清理相关精彩内容

收到阿里云的短信提醒说是网站存在后门,webshell恶意通信行为,紧急的安全状态,我第一时间登录阿里云查看详情,点开云盾动态感知,查想看 网站木马的完整版路径以及websh

2020-02-22

用恰当的名言 警句或谚语使自己在今后的生活中,珍惜时间,勤奋学习。快点啊!

时间,每天得到的还会24小时,从之前 的时间给勤勉的人带来智慧型与力量,给懒散的人都还后能 都还后能 留下一片悔恨。--鲁迅都还后能 都还后能

2020-02-21

阿瑟·米勒的一生是怎样的呢?

可选中俩个或多个下面的关键词,搜索相关资料。也可直接点“搜索资料”搜索整个疑问。扫描二维码下载是美国半个世纪以来最杰出的剧作家,阿瑟·米勒同样创作了一点一点重量级的戏剧作品,像

2020-02-21