1. Android S中APK(预编译)中的dex文件
例如Photos,
26M ./oat/arm/Photos.vdex 5.9M ./oat/arm/Photos.odex 1.4M ./oat/arm/Photos.art 33M ./oat/arm 33M ./oat 36K ./Photos.apk.prof 76M ./Photos.apk 108M .
vdex 文件
dex code + verification info 也就是dex 文件加上校验信息组成vdex 文件
那么dex文件又是什么 dex 文件
Android系统的可执行文件,包含应用程序的全部操作指令以及运行时数据。由于dalvik是一种针对嵌入式设备而特殊设计的java虚拟机,所以dex文件与标准的class文件在结构设计上有着本质的区别。 当java程序编译成class后,还需要使用dx工具将所有的class文件整合到一个dex文件,目的是其中各个类能够共享数据,在一定程度上降低了冗余,同时也是文件结构更加经凑,实验表明, dex文件是传统jar文件大小的50%左右。 DEX是Dalvik EXecutable的简称。在Android系统中,一个App的所有代码都在一个Dex文件里面。Dex是一个类似Jar的存储了多有Java编译字节码的归档文件。 因为Android系统使用虚拟机,所以需要把使用Java Compiler编译之后的class文件转换成虚拟机能够执行的class文件。这里需要强调的是,Dex和Jar一样是一个归档文件, 里面仍然是Java代码对应的字节码文件。 注意一点dex文件和jar文件一样,仍然是归档文件,代表的是java的字节码文件,可以先简单认为是apk的字节码文件
odex 文件
当Android系统启动一个应用的时候,有一步是对Dex进行优化,这个过程有一个专门的工具来处理,叫dex2oat。dex2oat的执行过程是在第一次加载Dex文件的时候执行的。 这个过程会生成一个odex文件,即Optimised Dex。执行odex的效率会比直接执行Dex文件的效率要高很多。odex文件存放在/data/dalvik-cache目录并在执行时加载进内存执行。 在APK的安装过程中,dex文件会被提取出来进行检查和验证。APK安装成功后,在第一次运行或系统第一次开机时,系统对dex文件进行优化,转换为odex文件。 这里就是优化过后的字节码 ,会比dex文件执行效率有很大的提升(如启动速度可以提升10%-30%)
art 文件:Android N开始出现,是app的image文件
这个文件里预加载了一些class,在应用运行时可以直接将AppImage映射到内存中,以加快类加载的速度。 是一个header+class object的映射内存数据,直接被映射到art虚拟机的堆空间中,包含oat/odex的某些对象实例以及函数。
prof 文件
记录着运行时的热点函数,用于生成odex、oat、art等优化文件
2. 安装/开机过程中的dex文件
普通安装是没有prof文件的,可以看到odex文件很小,也就代表基本上没有什么热点函数的优化
31M ./base.apk 96K ./oat/arm/base.odex 10M ./oat/arm/base.vdex 10M ./oat/arm 10M ./oat 46M .
默认开机过程中做的dex文件,这里的dex文件和上面的odex文件一样都是优化过后的问题,可以看到也是很小,也就是默认没有很大优化
/data/dalvik-cache/arm # du -ah | grep “Duo” 152K ./system@removable-app@Duo@Duo.apk@classes.dex 11M ./system@removable-app@Duo@Duo.apk@classes.vdex
3. 出现prof文件后,手动触发重新做一次dex2opt
如果使用过后出现prof,然后再次看whatsapp的内容,发现odex的大小明显增加了,还有art文件也明显增加了。 这个就是通过profile重新进行dex2opt生成更优的机器码的过程,各位可以自己测试一下,提升效能有10%-30%
31M ./base.apk 1.5M ./oat/arm/base.odex 9.4M ./oat/arm/base.vdex 500K ./oat/arm/base.art 11M ./oat/arm 11M ./oat 47M . /data/misc/profiles/ref/com.whatsapp # du -ah 8.0K ./primary.prof
4. system_server的dex文件
system_server系统进程可以说是android最重要的一个进程之一
4.0K ./services.jar.bprof 212K ./oat/arm/services.vdex 35M ./oat/arm/services.odex 2.2M ./oat/arm/services.art 18M ./services.jar 324K ./services.jar.prof
可以看到system_server其实是一个jar包, services.jar.bprof
boot image的prof文件
services.jar.prof
frameworks/base/services/art-profile热点函数转换成profile文件
frameworks/base/services/art-profile
system_server的热点函数
其中odex、art文件都很大,代表大部分都是优化后的(普通的Android版本system_server是做的speed优化,故odex会非常大;而art appimage文件是art-profile生成的)
5. Boot image 文件
boot***文件,ART虚拟机必须的一部分,没有它们无法启动:不同的是system_server是一个单独进程,而bootimage是运行在zygote中的,也就是所有上层进程 Android S system/framework中有很多boot文件,这里只列出boot-framework来做个代表
9.4M ./arm/boot-framework.oat 4.4M ./arm/boot-framework.art 316K ./boot-framework.vdex 34M ./framework.jar
boot**.oat :路径system/framework以及data/dalvik-cache/arm(arm64)
boot image文件的一部分,主要存放系统关键库的代码, 用来加速运行,类似于odex文件 可以将其理解为ART虚拟机的启动类(主要内容是代码,其中就包含了Android系统需要的基础jar包和java的核心jar包) 注:data下的由首次开机patchoat时做偏移得到(安全相关) boot**.art会加载在boot**.oat前面,内存中紧紧挨着boot**.oat
这个oat文件主要是通过 frameworks/base/config/boot-image-profile.txt 转换成boot image的profile文件,然后生成的优化文件
boot**.art
主要是数据——加载好的class信息以及一些事先创建好的对象preload-classes 也是通过boot image的profile文件来生成的,用于预加载
ps: 由于写一篇长的比较耗时,分成几次来写,下一个篇幅将用来讲解如何抓取profile文件
|