重点请参考Android运行时ART简要介绍和学习计划 包含类加载和方法的执行
一、ART对APK的优化
APK里面的Dex字节码是通过LLVM翻译成本地机器指令的。LLVM是一个用来快速开发自己的编译器的框架系统,
基于LLVM架构开发的编译器执行过程
ART中,APK在安装的时候,安装服务PackageManagerService会通过守护进程installd调用另dex2oat对打包在APK里面包含有Dex字节码进翻译。这个翻译器实际上就是基于LLVM架构实现的一个编译器,它的前端是一个Dex语法分析器。翻译后得到的是一个ELF格式的oat文件,这个oat文件同样是以.odex后缀结束,并且也是保存在/data/dalvik-cache目录中。
ELF是Linux系统使用的一种文件格式,我们平时接触的静态库、动态库和可执行文件都是以这种格式保存的,但是由dex2oat工具生成的oat文件与上述三种文件都不一样,它有两个特殊的段oatdata和oatexec,分别用来储存原来打包在APK里面的dex文件和翻译这个dex文件里面的类方法得到本地机器指令,如图所示:
在oat文件的动态段(dymanic section)中,还导出了三个符号oatdata、oatexec和oatlastword,分别用来描述oatdata和oatexec段加段到内存后的起止地址。在oatdata段中,包含了两个重要的信息,一个信息是原来的classes.dex文件的完整内容,另一个信息引导ART找到classes.dex文件里面的类方法所对应的本地机器指令,这些本地机器指令就保存在oatexec段中。
举个例子说,我们在classes.dex文件中有一个类A,那么当我们知道类A的名字后,就可以通过保存在oatdata段的dex文件得到类A的所有信息,比如它的父类、成员变量和成员函数等。另一方面,类A在oatdata段中有一个对应的OatClass结构体。这个OatClass结构体描述了类A的每一个方法所对应的本地机器指令在oatexec段的位置。也就是说,当我们知道一个类及其某一个方法的名字(签名)之后,就可以通过oatdata段的dex文件内容和OatClass结构体找到其在oatexec段的本地机器指令,这样就可以执行这个类方法了
OAT文件是一种Android私有ELF文件格式,它不仅包含有从DEX文件翻译而来的本地机器指令,还包含有原来的DEX文件内容。
OAT文件包含有两个特殊的段oatdata和oatexec,前者包含有用来生成本地机器指令的dex文件内容,后者包含有生成的本地机器指令,它们之间的关系通过储存在oatdata段前面的oat头部描述。此外,在OAT文件的dynamic段,导出了三个符号oatdata、oatexec和oatlastword,它们的值就是用来界定oatdata段和oatexec段的起止位置的。其中,[oatdata, oatexec - 1]描述的是oatdata段的起止位置,而[oatexec, oatlastword + 3]描述的是oatexec的起止位置。
参考
作者:罗升阳
原文:https://blog.csdn.net/Luoshengyang/article/details/39256813
网友评论