在这种情况下,我们依然可以在装有 Android 10 的 Pixel 2 XL 上循环运行了数千次分配对象的代码,因为对于小型或大型对象,性能可能会有所不同,我们还通过添加不同的字段来模拟不同的对象大小,最终的开销结果如下:
用于垃圾回收的 CPU 开销的结果如下:
从图中可以看出,标准分配和池化对象之间的差异也很小,但是,当涉及到较大对象的垃圾回收时,池解决方案略微高一点。
这个结果并不意外,因为池化对象会增加应用的内存占用量,此时,应用突然占用了太多的内存,即使由于池化对象减少了垃圾回收调用的数量,每个垃圾回收调用的成本也更高,因为垃圾收集器必须遍历更多的内存才能确定哪些对象需要被收集,哪些对象需要保留。
那么,对象是否应该被池化,这还是主要取决于应用的需求。如果不考虑到代码复杂性,池化对象有如下缺点:
- 提高内存占用量
- 使对象存活变长
- 需要非常完善的对象池机制
但是,池的方法对于大并且耗时的对象分配可能确实是有效的,关键是要记住在选择方案之前进行充分的测试。
误区五:debug 模式下进行性能分析
在 debug 的同时对应用进行性能分析非常方便,毕竟,我们通常也是在 debug 模式下进行编码的,并且,即使 debug 应用中的性能分析不准确,也可以更快地进行迭代修改提高效率,然后事实是并没有。
为了验证这一误解,我们分析了 Activity 相关的常见操作过程过的测试结果,如下图:
在某些测试(例如反序列化)中,debug 与否对性能没有影响,但是,有些结果却有 50% 甚至以上的差别,我们甚至发现结果速度可能会慢 100% 的例子,这是因为 runtime 在 debug 模式下时对代码几乎没有优化,因此与用户在生产设备上运行的代码有很大不同。
在 debug 模式下进行性能分析的结果是可能会误导优化方向,导致浪费时间来优化不需要优化的内容。
疑点
现在,我们需要有意识的逃避上述提到的五大误区,下面我们再来看一下一些日常开发中不太明显,但我们经常会有的疑惑的问题,事实结果可能也与我们想的大相径庭。
疑点 1:Multidex:是否影响应用性能?
如今的 APK 文件越来越大,因为大型应用通常会超出 Android 限定的方法数量,从而使用 Multidex 方案打破传统的 dex 规范。
问题是,多少方法可以称之为多?而且如果应用包含大量 dex 是否对性能产生影响?很多时候我们也并不是因为应用太大,而是为了根据功能拆分 dex 文件来方便团队开发而使用 Multidex。
为了测试多个 dex 文件对性能的影响,我们使用了计算器应用,默认情况下,它只包含单个 dex 文件,我们可以根据其程序包边界将其拆分为五个 dex 文件,来根据功能部件模拟拆分。
首先,测试启动应用的性能,结果如下:
因此,拆分 dex 文件对此处并没有影响,对于其他应用,可能会因为某些因素而产生轻微的开销:应用程序的大小以及拆分方式。但是,只要合理地分割 dex 文件并且不添加成百个 dex 文件,对启动时间的影响应该不大。
接下来是 APK 的大小和内存消耗:
如图所示,APK 大小和应用的运行时内存占用量都略有增加,这是因为将应用程序拆分为多个 dex 文件时,每个 dex 文件都会有一些符号表和缓存表中的重复数据。
但是,我们可以通过减少 dex 文件之间的依赖关系来最大限度地避免这种情况,在这个案例中,并没有将 dex 包量化,我们可以使用 R8 和 D8 之类的工具合理分析项目结构并使用最小化的依赖关系,这些工具可以自动拆分 dex 文件,并帮助我们避免常见的错误,最大程度地减少依赖关系,如创建的 dex 文件数量不会超过指定的数量,并且不会将所有启动类都放置在主文件中。但是,如果我们对 dex 文件进行自定义拆分,请确保合理分析。
疑点 2:无用代码
使用 ART 这样的即时编译器的好处之一就是可以在运行时分析代码,并对其进行优化。有一种说法是,如果解释器 / JIT 系统没有对代码进行概要分析,就可能不会执行该代码。为了验证这一理论,我们检查了 Google 应用生成的 ART 配置文件,发现许多代码并没有被 JIT 做概要分析,这就表明许多代码实际上从未在设备上执行过。
有几种类型的代码可能无法剖析:
- 错误处理代码,希望它不会执行太多。
- 兼容性代码,并非在所有设备上都执行的代码,尤其是 Android 5 以上版本的设备。
- 不常用功能的代码。
但是,从结果分布来看,应用程序中还是会存在很多不必要的代码。R8 可以帮助我们快速,简便,免费地删除不必要的代码,来缩小这部分的开销。如果不这么做,我们也可以将应用打包成 Android App Bundle,这种格式只会使用特定设备所需的代码和资源来运行应用。
总结
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
文末
架构师不是天生的,是在项目中磨练起来的,所以,我们学了技术就需要结合项目进行实战训练,那么在Android里面最常用的架构无外乎 MVC,MVP,MVVM,但是这些思想如果和模块化,层次化,组件化混和在一起,那就不是一件那么简单的事了,我们需要一个真正身经百战的架构师才能讲解透彻其中蕴含的深理。
一线互联网Android面试题总结含详解(初级到高级专题)
一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算
、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算**