原文详见:http://www.netmite.com/android/mydroid/dalvik/docs/dexopt.html
dalvik的设计的初衷就是运行在像Android这样的小RAM,低速度flash memory,运行标准Linux系统的设备。针对这样的平台特性,要想做到更好,我们需要考虑以下几点:
1)为了减少系统的内存使用,字节码可以多进程共享。但出于安全性考虑,这样的字节码不可以编辑。
2)为了保证响应速度,加载一个新的APP所需时间尽量少。
3)标准Java中把多个类文件分别存放导致了大量的冗余,为了节省APP的占用空间,这个问题要解决。
4)加载类的时候解析类的字段成员会导致额外的消耗,如果改成像C一样直接访问会比较好。
5)字节码verification很有必要,但很慢,我们需要把验证与APP执行分开。
6)字节码optimization(比如指令优化、方法pruning)可以在很大程度上影响执行速度和电池消耗。
标准VM都是程序启动时把每单个的类文件解压放入heap,每个进程都有一份copy。这样的做法在内存占用和时间上面都有损失,但方便了对指令的优化。
现在看看dalvik是怎么做的:
1)多个类被集成进单一的DEX文件。
2)DEX文件在进程间以只读方式共享。
3)byte ordering和word alignment根据local system来做调整。
4)字节码verification尽可能提前。
5)需要修改字节码的optimization必须提前进行。
这样做的好处在下面一一介绍。
VM Operation
系统中的应用程序代码以.jar或.apk文件存在。其实它们都是.zip的文档,只不过多了一些文件头信息。DEX文件也就是解压.apk后的classes.dex文件。classes.dex中的字节码是经过压缩处理的,而且文件头部不一定是word aligned,所以不能直接mmap到内存直接执行,而是先解压,然后做一些realignment,optimization,verification操作。下面详细介绍一下这个过程。
Preparation
做到DEX文件的执行前优化(优化后的DEX叫做ODEX,Optimization DEX),至少有三种方式:
1)VM的JIT技术。优化后的文件放在/data/dalvik-cache目录下。这种方式在模拟器和eng模式下编译的系统中有效,只有这两种情况下操作dalvik-cache目录才不会有权限问题。
2)安装应用程序时,system installer做优化。这需要dalvik-cache目录的写权限。
3)编译系统源码时进行优化。这样优化不会修改jar/apk文件,但会对classes.dex进行优化,优化后的DEX与原文件放在同一个目录下一起写入system image。
系统中的/data/dalvik-cache目录属于system/system,权限是0771。存储在这个目录下的ODEX文件被system和应用程序所属的group拥有,权限是0644。DRM-locked的应用程序使用640权限。底线是你可以读你自己的DEX文件和其它的大多数应用程序,但不能创建、修改或删除它们。
使用JIT和system installer做DEX文件的Preparation要分成三步:
1)由system installer创建dalvik-cache文件夹,这个程序运行在有root权限的installd进程中。
2)classes.dex被解压出来,并在文件头部预留一些空间存放ODEX头信息。
3)为了方便使用和做一些针对特定系统的微调,把它mmap。比如byte-swapping,structure realigning等。我们还会做一些像文件偏移量和数据索引是否越界等方面的基本检查。
编译系统使用一个很复杂的流程来做这些事:启动模拟器,强制对所有相关DEX文件执行JIT优化,最后把优化后的结果从dalvik-cache中提取出来。之所以这样做而不是在PC上面使用一个工具来完成,在后面解释Optimization时可以看到原因。
当代码的byte-swapping和align完成时,我们的preparation就完成了。再做完verification和optimization,最后,我们就会把一些相关计算出来的信息添加到ODEX文件的头部然后开始执行。
dexopt
其实,如果我们想优化DEX中的类文件的话,最简单最安全的办法就是把所有类加载到VM中然后运行一遍,运行失败的就是没有verification和optimization的。但是,这样会分配一些很难释放的资源。比如,加载本地库时。所以,不能使用运行程序的那个VM来做。
我们的解决方案就是使用dexopt这个程序,它会初始化一个VM,加载DEX文件并执行verification和optimization过程。完成后,进程退出,释放所有资源。这个过程中,也可以多个VM使用同一个DEX。file lock会让dexopt只运行一次。
verification
字节码的verification过程涉及到每个DEX文件中的所有类和类中的所有方法中的指令。目标就是检查非法指令序列,这样做完以后,运行的时候就不必管了。这个过程中涉及到的许多计算也存在于GC过程中。
出于效率上的考虑,下一节提到的optimization会假设verification已经成功运行通过。默认情况下,dalvik会对所有类进行verification,而只对verification成功的类执行optimization。在进行verification过程中出现失败时,我们不一定会报告(比如在不同的包中调用一个作用范围为包内的类),我们会在执行时抛出一个异常。因为检查每个方法的访问权限很慢。
执行verification成功的类在ODEX文件中有一个flag set,当它们被加载时,就不会再进行verification。linux系统的安全机制会防止这个文件被破坏,但如果你能绕过去,还是能去破坏它的。ODEX文件有一个32-bit的checksum,但只能做一个快速检查。
Optimization
VM解释器在第一次运行一段代码时会做一些optimization。比如,把常量池引用替换成指向内部数据结构的指针,一些永远成功的操作或固定的代码被替换成更简单的形式。做这些optimization需要的信息有的只能在运行时得到,有的可以推断出来。
dalvik做的optimization包含下面这些:
1)对于虚方法的调用,把方法索引修改成vtable索引。
2)把field的get/put修改成字节偏移量。把boolean/byte/char/short等类型的变量合并到一个32-bit的形式,更少的代码可以更有效地利用CPU的I-cache。
3)把一些大量使用的简单方法进行inline,比如String.length()。这样能减少方法调用的开销。
4)删除空方法。
5)加入一些计算好的数据。比如,VM需要一个hash table来查找类名字,我们就可以在Optimization阶段进行计算,不用放到DEX加载的时候了。
所有的指令修改都是使用一个Dalvik标准没有定义的指令去替换原有指令。这样,我们就可以让优化和没有优化的指令自由搭配。具体的操作与VM版本有关。
Optimization过程有两个地方需要我们注意:
1)VM如果更新的话,vtable索引和字节偏移量可能会更新。
2)如果两个DEX互相信赖,而其中一个DEX更新的话,确保优化后的索引和偏移量有效。
Dependencies and Limitations
优化后的DEX会包含一个它信赖的DEX文件列表,并添加了CRC-32和修改时间。文件列表中包含了dalvik-cache目录下的文件的路径和相应的SHA-1签名。而文件在设备上的timestamp不可信也不能用。另外还有VM版本号。
如果当前DEX所依赖的DEX有更新,我们也需要更新当前DEX。如果我们可以做一个JIT的dexopt调用,更新过程很easy。但如果只能依赖installer daemon,或者这个DEX被装到ODEX中的话,VM只能拒绝它了。
dexopt的输出与平台版本,VM版本有关,想编写一个运行在PC上,而优化后的输出在其它设备使用的dexopt很难。因此,dexopt是在目标设备上或者目标设备的模拟器上运行。
分享到:
相关推荐
- **dexopt**:这是Dalvik源码的一部分,用于预编译.dex文件,进行优化,如常量池合并、方法内联等,以提高运行时性能。 - ** oat文件**:在Android系统中,dex文件会通过dex2oat工具转换为.oat文件,这是一个包含...
这一提示意味着系统正在进行必要的优化和准备工作,确保后续的操作更加流畅。本文将深入探讨这一提示背后的实现原理,以及它在Android启动过程中的作用。 #### 二、DexOpt优化概述 当Android系统启动时,会对系统...
这涉及到dex文件(Dalvik Executable Format)的读取,以及可能的优化过程(DexOpt),优化后的.dex文件会被存储在设备的缓存区域以提高后续运行效率。 6. **指令解析与执行**:Dalvik虚拟机使用字节码解释器执行....
尽管如此,开发者仍然可以在运行时对dex文件进行优化,比如使用`dexopt`工具进行编译优化。 3. **Xposed框架**:这是一个广泛使用的第三方框架,它允许开发者通过修改系统函数调用来改变应用的行为。Xposed基于hook...
在应用安装时,Android系统会通过 DexOpt 对 .dex 文件进行优化,生成 .odex 文件,这个过程称为Dalvik优化。这包括预解析(Preverification)、字节码简化(Dalvik Bytecode Simplification)和数据流分析(Data ...
为了方便开发者调试和优化应用,Android提供了Dalvik Debug Monitor Service(DDMS)和Android Debug Bridge(ADB)。DDMS提供内存分析、线程监控和堆栈跟踪等功能,而ADB则是连接设备进行日志输出和文件传输的重要...
这个过程叫做dex 文件解析和验证,确保字节码的合法性。 7. **虚拟机运行时环境** Dalvik 提供了类装载器、异常处理、线程调度等功能。它还支持动态代码加载和修改,使得开发者可以通过 DexClassLoader 动态加载新...
总结来说,动态加载APK是Android插件机制的一种实现方式,通过重写类加载器、DexOpt优化和反射等技术,实现了应用程序在运行时动态加载和使用外部APK的能力。这项技术在提升软件的灵活性、可维护性和安全性方面具有...
android的虚拟机dalvik源码: run-core-tests.sh Android.mk NOTICE MODULE_LICENSE_APACHE2 README.txt /libdex /libcore-disabled /dexopt /libcore /tools /tests /libnativehelper /dexlist /dexdump /dalvikvm ...
在Android系统中,"odex"(Optimized Dalvik Executable)是Dalvik虚拟机执行的优化过的字节码文件,它将Dalvik字节码(.dex)进行了预编译,以提高应用程序的启动速度和运行效率。"android手机端odex化"指的是将...
DEX优化是Android系统在安装应用时进行的一项步骤,它包括预加载优化(pre-DexOpt)和即时优化(on-demand DexOpt)。如果在这些过程中出现问题,就会出现INSTALL_FAILED_DEXOPT错误。 当遇到此错误时,可以尝试...
同时完全允许代码中的所有预优化和代码,允许所有不安全的非托管代码,同时不严谨的程序如果运行在 JIT 模式可能会造成内存泄露。但要注意,很多Dalvik 虚拟机并不支持此模式(如官方 2.2)。 6. dalvik.vm.dexopt-...
优化主要包括代码优化、资源优化和构建过程优化。代码优化涉及减少冗余代码,使用更高效的算法,以及利用ProGuard或R8工具进行混淆,以减小APK大小并提高运行时性能。资源优化包括压缩图片、去除未使用的资源,以及...
odex和apk合成dex 一、APK生成odex文件方法: 编译开源GIT上的build/tools/dexpreopt/dexopt-wrapper这个,使用dexopt-wrapper即可,操作步骤 将dexopt-wrapper放到/data/local目录中,使用adb shell执行linux...
**优化和Dalvik Just-In-Time (JIT)** 为了提高性能,Android系统还引入了Dalvik JIT编译器。JIT编译器会在程序运行时将部分频繁执行的字节码编译成本地机器代码,从而减少解释执行的开销。这种即时编译技术使得...
- **DexOpt优化的限制**:DexOpt是一个在Android系统启动时对Dex文件进行优化的过程,它会生成一个Optimized Dex(ODex)文件以提高运行效率。在早期版本中,DexOpt将每个类的方法ID存储在一个链表中,但由于链表...
在执行本地机器指令的过程中,ART通过在应用安装时,由安装服务PackageManagerService通过守护进程installd调用工具dexopt来优化包含Dex字节码的classes.dex。优化后生成的文件是预编译后的本地代码,为ART运行时...
除了`zipalign.exe`,Android还提供了其他优化工具,如ProGuard(用于代码混淆和优化)和dexopt(用于优化Dalvik字节码)。这些工具的合理运用,可以显著提升应用的运行效率,减小安装包大小,并增强应用的安全性。 ...
然而,当APK被安装到设备上时,系统会对其进行编译和优化,生成一个名为"ODEX"(Optimized Dalvik Executable)的文件。这个过程叫做“dex优化”,目的是为了提高应用运行时的效率。"ODEX工具包"就是为了帮助开发者...
5. **dexopt工具**:这个工具可以优化DEX文件,使其在运行时更高效,通常在安装应用时由系统自动执行。 6. **apksigner工具**:用于签名APK文件,这是发布到Google Play或其他Android市场所必需的步骤。 7. **...