2024年Android性能调优之需要掌握Dalvik和ART的知识,面试加分句

总结

【Android 详细知识点思维脑图(技能树)】

我个人是做Android开发,已经有十来年了,目前在某创业公司任职CTO兼系统架构师。虽然 Android 没有前几年火热了,已经过去了会四大组件就能找到高薪职位的时代了。这只能说明 Android 中级以下的岗位饱和了,现在高级工程师还是比较缺少的,很多高级职位给的薪资真的特别高(钱多也不一定能找到合适的),所以努力让自己成为高级工程师才是最重要的。

这里附上上述的面试题相关的几十套字节跳动,京东,小米,腾讯、头条、阿里、美团等公司19年的面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。

由于篇幅有限,这里以图片的形式给大家展示一小部分。

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

最后,赠与大家一句话,共勉!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

而JVM机制不存在这种共享机制,不同的程序在打包以后的程序都是彼此独立的。

即使它们在包里使用了相同的类,运行时都是单独加载和运行的,无法进行共享。

6.DVM早期没有使用JIT编译器

JVM使用了JIT(Just in time 即时编译器)编译器,而DVM早期没有使用JIT编译器。

早期的DVM每次执行代码,都需要通过解释器将dex代码编译成机器码,然后交给系统,效率并不高。

为了解决这个问题,在Android2.2开始DVM使用JIT,它会对多次运行的代码(热点代码)进行编译,生成相当精简的本地机器码,这样在下次执行相同逻辑的时候,直接使用编译之后的本地机器码,而不是每次都需要编译。

需要注意的是,应用程序每次重新运行的时候,都要重做这个编译工作,因此每次重新打开应用程序,都需要JIT编译。

1.2 DVM架构


DVM的源码位于dalvik/目录下,部分目录说明如下所示:

  • Android.mk

是虚拟机编译的makefile文件

  • vm

包含虚拟机绝大多数代码,包括虚拟机初始化及内存管理的代码

  • dx

生成将Java字节码转换为DVM机器码的工具

  • hit

生成显示堆栈信息/对象信息的工具

  • libdex

生成主机和设备处理dex文件的库

  • dexopt

生成dex优化工具

  • dexdump

生成.dex文件反编译查看工具,主要是用来查看编译出来的代码的正确性和结构

  • dexlist

此目录是生成查看dex文件里所有类的方法的工具

  • dexgen

.dex文件代码生成器项目

  • docs

DVM相关帮助文档

  • tools

一些编译和运行相关的工具

  • MODULE_LICENSE_APACHE2

APACHE2版权声明文件

  • NOTICE

虚拟机源码版权注意事项文件

其中 libdex会被编译成 libdex.a 静态库,作为dex工具使用。DVM架构如下图所示:

在这里插入图片描述

1.3 DVM的运行时堆


DVM的运行时堆使用标记-清除算法进行GC。

它由两个Space以及多个辅助数据结构组成。两个Space分别是Zygote Space(Zygote Heap)和Allocation Space(Active Heap),下面为他们的说明

  • Zygote Space

用来管理Zygote进程在启动过程中预加载和创建的各种对象,Zygote Space中不会触发GC。

在Zygote进程和应用程序进程之间会共享Zygote Space。在Zygote进程fork第一个子进程之前,会把Zygote Space分成两个部分,原来的已经被使用的那部分堆仍叫Zygote Space,而未使用的那部分堆就叫做Allocation Space

  • Allocation Space

之后的对象都会在Allocation Space上进行分配和释放。Allocation Space不是进程间共享的,在每个进程中都独立拥有一份。

  • Card Table

用于DVM Concurrent GC,当第一次进行垃圾标记后,记录垃圾信息

  • Heap Bitmap

有两个Heap Bitmap,一个用来记录上次GC存活的对象,另一个用来记录这个GC存活的对象

  • Mark Stack

DVM的运行时堆使用 标记-清除算法进行GC,Mark Stack就是在GC的标记阶段使用的,它用来遍历存活的对象。

1.4 DVM的GC日志


DVM和ART的GC日志与JVM的日志有很大的区别。

在DVM中每次垃圾的收集都会将GC日志打印到logcat中,具体的格式为:

D/dalvikv: <GC_Reason> <Amount_freed>, <Heap_stats>, <External_memory_stats>, <Pause_time>

可以看到DVM的日志共有5个信息,其中GC Reason有很多种,这里将它单独拿出来进行介绍。

1.引起GC的原因

GC Reason 就是引起GC的原因,有以下几种。

  • GC_CONCURRENT:当堆开始填充的时,并发GC可以释放内存

  • GC_FOR_MALLOC:当内存堆已满时,App尝试分配内存而引起的GC,系统必须停止App并回收内存。

  • GC_HPROF_DUMP_HEAP:当你请求创建HPROF文件来分析堆内存时出现的GC

  • GC_EXPLITCIT:显示的GC。例如调用System.gc()

  • GC_EXTERNAL_ALLOC:仅适用API<=10,且用于外部分配内存的GC

2.其他的信息

  • Amout_freed

本次GC释放内存的大小

  • Heap_stats

堆的空闲内存百分比:(已用内存)/(堆的总内存)

  • External_memory_stats

API<=10的内存分配 (已分配的内存)/(引起GC的阈值)

  • Pause time

暂停时间,更大的堆会有更长的暂停时间。并发暂停时间会显示两个暂停时间,即一个出现在垃圾收集开始时,另一个出现在垃圾收集快要完成时。

3.实例分析

拿logcat中的GC举个例子:

D/dalvikvm: GC_CONCURRENT freed 2012k, 63% free 3213K/9291K, external 4501K/5161K, paused 2ms+2ms

意思就是:引起GC的原因是GC_CONCURRENT,本次GC释放的内存为2012KB,堆的空闲内存百分比为63%,已经使用内存为3213K,堆的总内存为9291K,暂停的总时长为4ms

2.ART虚拟机

=========================================================================

ART在Android5.0完全取代了DVM

2.1 ART与DVM的区别


  • DVM中应用每次运行时,字节码都需要通过JIT编译为机器码,这会使得应用程序的运行效率降低,而在ART中系统在安装应用程序时会进行一次 AOT(ahead of time compilation,预编译),将字节码预先编译成机器码并存储在本地,这样应用程序每次运行程序时就不需要执行编译了,运行效率大大的提高了。设备的耗电量也会降低。

采用AOT预加载也有两个主要的缺点:

一是AOT会使得应用程序的安装时间边长

二是字节码预先编译成机器码,机器码需要存储空间会更多一些(这里就是空间换时间了)

为了解决上面的缺点,在Android7.0的版本中ART加入了JIT,作为AOT的一个补充,在应用程序安装时并不会将字节码全部编译成机器码,而是在运行中将热点代码编译成机器码,从而缩短应用程序的安装时间并节省了存储空间。

  • DVM是为32位CPU设计的,而ART支持64位并兼容32位CPU,这也是DVM被淘汰的主要原因之一

  • ART对垃圾回收机制进行了改进,比如更频繁的执行GC,将GC暂停由两次减小为一次

  • ART的运行时堆空间划分和DVM不同

2.2 ART的运行时堆


与DVM的GC不同的是,ART采用了多种垃圾收集方案,每个方案会运行不同的垃圾收集器,默认采用的是CMS(Concurrent Mark-Sweep)方案,该方案主要是使用了 sticky——CMS和 partial-CMS,根据不同的CMS方案,ART的运行时堆的控件也会有不同的划分,默认是由4个Space和多个辅助数据结构组成的。4个Space分别是 Zygote Space、Allocation Space、Image Space和Large Object Space。 前两个和DVM中的作用是一样的。

  • Image Space

用来存放一些预加载类

  • Large Obejct Space

用来分配一些大对象(默认大小为12KB)

其中Zygote Space和Image Space是进程间共享的空间。

除了这四个Space,ART的Java堆还包括两个 Mod Union Table,一个Card Table,两个 Heap Bitmap、两个Object Map以及三个Object Stack

2.3 ART的GC日志


ART的GC日志和DVM不同是,ART会为那些主动请求的垃圾收集事件或者认为GC速度慢时才会打印GC日志。

GC速度慢是指GC暂停时间超过5ms或者GC持续时间超过100ms。如果App未处于可察觉的暂停进程状态,那么它的GC不会被认为是慢速的。

ART的GC日志具体格式为:

I/art: <GC_REASON> <GC_NAME> <Objects_freed>(<Size_freed>) AllocSpace Objects,

<Large_objects_freed>(<Large_object_suze_freed>) <Heap_stats> Losobjects,

<Pause_time(s)>

1.引起GC原因

ART引起GC的原因要比DMV多一些

  • Concurrent

并发GC,不会使App线程暂停,该GC是在后台线程中进行的,并不会组织内存分配

  • Alloc

当内存已满时,App尝试分配内存而引起的GC,这个GC会发生在正在分配内存的线程中

  • Explicit

结语

  • 现在随着短视频,抖音,快手的流行NDK模块开发也显得越发重要,需要这块人才的企业也越来越多,随之学习这块的人也变多了,音视频的开发,往往是比较难的,而这个比较难的技术就是NDK里面的技术。
  • 音视频/高清大图片/人工智能/直播/抖音等等这年与用户最紧密,与我们生活最相关的技术一直都在寻找最终的技术落地平台,以前是windows系统,而现在则是移动系统了,移动系统中又是以Android占比绝大部分为前提,所以AndroidNDK技术已经是我们必备技能了。
  • 要学习好NDK,其中的关于C/C++,jni,Linux基础都是需要学习的,除此之外,音视频的编解码技术,流媒体协议,ffmpeg这些都是音视频开发必备技能,而且
  • OpenCV/OpenGl/这些又是图像处理必备知识,下面这些我都是当年自己搜集的资料和做的一些图,因为当年我就感觉视频这块会是一个大的趋势。所以提前做了一些准备。现在拿出来分享给大家。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

个大的趋势。所以提前做了一些准备。现在拿出来分享给大家。

[外链图片转存中…(img-VP5nZ29g-1715595819506)]

[外链图片转存中…(img-uKmT6SAs-1715595819507)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 16
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值