Dart | Davlik |
---|---|
AOT(Ahead Of Time)编译 | |
JIT(Just In Time) 编译 | |
热重载 | Instant Run |
垃圾回收(分代垃圾回收和对象分配方案,几乎可以在没有锁的情况下执行垃圾回收) |
传统的代码修改及编译流程如下:构建整个apk → 部署app → app重启 → 重启Activity
Instant Run构建项目的流程:构建修改的部分 → 部署修改的dex或资源 → 热部署(直接查看修改),温部署(重启Activity),冷部署 (重启app)
准备:先将修改的文件存放到压缩包 instant-run.zip 中。
启动:
- app 首先是修改 ClassLoader,将原有的BootClassLoader → PathClassLoader 改为 BootClassLoader → IncrementalClassLoader → PathClassLoader 的继承关系。
- createRealApplication
- 反射替换ActivityThread中的各种Application成员变量,AssetManager对象
- 调用realApplication的onCreate方法
修复:
- 在第一次构建apk时,在每一个类中注入了一个
change 不为空,就执行 IncrementalChange方法
- 当我们修改代码中方法的实现之后,点击InstantRun,它会生成对应的patch文件来记录你修改的内容。patch文件中的替换类是在所修改类名的后面追加$override,并实现IncrementalChange接口。
- 生成AppPatchesLoaderImpl类,继承自AbstractPatchesLoaderImpl,并实现getPatchedClasses方法,来记录哪些类被修改了。
- 打包成patch,通过socket传递给app
- app的server接收到patch之后,分别按照handleColdSwapPatch、handleHotSwapPatch、handleResourcePatch 等待对patch进行处理
- 如果后缀为“.dex”,冷部署处理handleColdSwapPatch
- 如果后缀为“classes.dex.3”,热部署处理handleHotSwapPatch
- 其他情况,温部署,处理资源handleResourcePatch
- restart使patch生效
DVM和JVM
JVM是Java Virtual Machine,而DVM就是Dalvik Virtual Machine。以下简要对比两种虚拟机的不同。
- JAVA虚拟机运行的是JAVA字节码,Dalvik虚拟机运行的是Dalvik字节码
JAVA程序经过编译,生成JAVA字节码保存在class文件中,JVM通过解码class文件中的内容来运行程序。而DVM运行的是Dalvik字节码,所有的Dalvik字节码由JAVA字节码转换而来,并被打包到一个DEX(Dalvik Executable)可执行文件中,DVM通过解释DEX文件来执行这些字节码。 - Dalvik可执行文件体积更小
class文件中包含多个不同的方法签名,如果A类文件引用B类文件中的方法,方法签名也会被复制到A类文件中。也就是说,多个不同的类会同时包含相同的方法签名,同样地,大量的字符串常量在多个类文件中也被重复使用,这些冗余信息会直接增加文件的体积,而JVM在把描述类的数据从class文件加载到内存时,需要对数据进行校验、转换解析和初始化,最终才形成可以被虚拟机直接使用的JAVA类型,因为大量的冗余信息,会严重影响虚拟机解析文件的效率。
为了减小执行文件的体积,安卓使用Dalvik虚拟机,SDK中有个dx工具负责将JAVA字节码转换为Dalvik字节码,dx工具对JAVA类文件重新排列,将所有JAVA类文件中的常量池分解,消除其中的冗余信息,重新组合形成一个常量池,所有的类文件共享同一个常量池,使得相同的字符串、常量在DEX文件中只出现一次,从而减小了文件的体积。
- JVM基于栈,DVM基于寄存器
关于栈式虚拟机:
1.代码必须使用这些指令来移动变量(即push和pop)
2.代码尺寸小和解码效率会更高些
3.堆栈虚拟机指令有隐含的操作数。
关于寄存器式虚拟机:
1.使用堆栈来分配激活记录器
2.基于寄存器代码免去了使用push和pop命令的麻烦,减少了每个函数的指令总数。
3.代码尺寸和解码效率不如基于栈虚拟机,因为它包含操作数,所以指令大于基于堆栈的指令。但是基于寄存器产生更少的代码,所以总的代码数不会增加。
4.寄存器虚拟机必须从操作指令中解码操作数,需要额外的解码操作。
ART 与 JVM/DVM
- JIT(Just In Time,即时编译技术)
JIT会在运行时分析应用程序的代码,识别哪些方法可以归类为热方法,这些方法会被JIT编译器编译成对应的汇编代码,然后存储到代码缓存中,以后调用这些方法时就不用解释执行了,可以直接使用代码缓存中已编译好的汇编代码。这能显著提升应用程序的执行效率。
- Dalvik虚拟机执行的是dex字节码,ART虚拟机执行的是本地机器码
Dalvik执行的是dex字节码,依靠JIT编译器去解释执行,运行时动态地将执行频率很高的dex字节码翻译成本地机器码,然后在执行,但是将dex字节码翻译成本地机器码是发生在应用程序的运行过程中,并且应用程序每一次重新运行的时候,都要重新做这个翻译工作,因此,及时采用了JIT,Dalvik虚拟机的总体性能还是不能与直接执行本地机器码的ART虚拟机相比。
从Dalvik虚拟机替换成ART虚拟机,应用程序仍然是一个包含dex字节码的apk文件。在安装应用的时候,dex中的字节码将被编译成本地机器码,之后每次打开应用,执行的都是本地机器码。移除了运行时的解释执行,效率更高,启动更快。
ART优点:
- 系统性能显著提升
- 应用启动更快、运行更快、体验更流畅、触感反馈更及时
- 续航能力提升
- 支持更低的硬件
ART缺点
- 更大的存储空间占用,可能增加10%-20%
- 更长的应用安装时间
网友评论