Android 性能优化技术月报 | 2024 年 3 月
每个月都会有一些 Android 性能优化相关的优质内容发布,然而,碎片化阅读使得这些知识难以形成完整体系,且容易被遗忘。为解决这些问题,我决定尝试使用技术月报的形式,总结我在最近一个月内查阅的 Android 性能优化相关的优质内容。
月报的主要内容包括:整理展示我在最近一个月所查阅的 Android 性能优化领域的最新技术动态、精选博客,精选视频等内容。
最新动态
《Android性能优化入门与实战》已上架
Android性能优化入门与实战》已上架, 书籍内容主要包括「市场需求、认识性能优化/测试、专项优化」三部分,分别介绍:
- 不同级别安卓需要具备的知识点、优秀的开发者素质是什么
- 性能优化和性能测试的方法论
- 内存/卡顿/启动优化的线上线下优化方式等
精选博客
32 位与 64 位到底有什么区别?
大家都知道 32 位应用虚拟内存占用最多是4G,而 64 位应用虚拟内存占用最多可达 256TB。那么 32 位 CPU 与 64 位 CPU 是如何影响应用虚拟内存上限的呢?
CPU 和内存以及其他设备之间,需要通信,因此我们用一种特殊的设备进行控制,就是总线。总线分成 3 种:
- 地址总线,专门用来指定 CPU 将要操作的内存地址
- 数据总线,用来读写内存中的数据
- 控制总线,用来发送和接收关键信号,比如中断信号,还有设备复位、就绪等信号,都是通过控制总线传输。CPU 需要对这些信号进行响应,这也需要控制总线。
32位CPU和64位CPU的区别之一就是,CPU 的位宽决定能控制的总线根数,而总线的根数决定寻址能力。32位最大控制的总线为32根,最大寻址能力是4G,64位最大控制的总线为64根,最大寻址能力是256TB。
为什么要有虚拟内存?
为了在多进程环境下,使得进程之间的内存地址不受影响,相互隔离,于是操作系统就为每个进程独立分配一套虚拟地址空间,每个程序只关心自己的虚拟地址就可以,实际上大家的虚拟地址都是一样的,但分布到物理地址内存是不一样的。作为程序,也不用关心物理地址的事情。
那既然有了虚拟地址空间,那必然要把虚拟地址「映射」到物理地址,这个事情通常由操作系统来维护。那么对于虚拟地址与物理地址的映射关系,可以有分段和分页的方式,同时两者结合都是可以的。
内存分段是根据程序的逻辑角度,分成了栈段、堆段、数据段、代码段等,这样可以分离出不同属性的段,同时是一块连续的空间。但是每个段的大小都不是统一的,这就会导致外部内存碎片和内存交换效率低的问题。
于是,就出现了内存分页,把虚拟空间和物理空间分成大小固定的页,如在 Linux 系统中,每一页的大小为 4KB。由于分了页后,就不会产生细小的内存碎片,解决了内存分段的外部内存碎片问题。同时在内存交换的时候,写入硬盘也就一个页或几个页,这就大大提高了内存交换的效率。再来,为了解决简单分页产生的页表过大的问题,就有了多级页表。
Linux 系统主要采用了分页管理,但是由于 Intel 处理器的发展史,Linux 系统无法避免分段管理。于是 Linux 就把所有段的基地址设为 0,也就意味着所有程序的地址空间都是线性地址空间(虚拟地址),相当于屏蔽了 CPU 逻辑地址的概念,所以段只被用于访问控制和内存保护。另外,Linux 系统中虚拟空间分布可分为用户态和内核态两部分,其中用户态的分布:代码段、全局变量、BSS、函数栈、堆内存、映射区。
经验 | 向AOSP贡献虚拟机的优化
本文主要讲述了作者向AOSP(Android Open Source Project)贡献虚拟机优化的经验。
文章详细记录了从最初的想法到最终代码提交的全过程,包括确定方案、下载代码、配置环境、开发、测试、测算效果、优化代码格式和性能、提交以及回撤等步骤。
作者分享了自己在这一过程中的心得体会,特别是在ART(Android Runtime)虚拟机内部进行系统性开发的经验。文章也提到了在开发过程中遇到的挑战和解决方案,以及与Google工程师的协作经历。
总得来说,看不太懂,只能说作者太牛了。
精选视频
社区说|我在 B 站做工程效能
本视频从哔哩哔哩当前的工程效能体系出发,介绍哔哩哔哩如何在 MonoRepo 中的编译构建相关的优化,以及对于工程结构的一系列理解。
社区说|快手的秒级编译探索之路
在快手这类超大型Android项目中,常规的编译优化手段已经无法解决构建劣化问题。本视频介绍了快手团队是如何在超大型项目中实现秒级编译的。