Android如何执行代码

Android开发者使用Java,不过Android平台不用Java虚拟机(VM)来执行代码。而是把应用编译成Dalvik字节码(5.0以后Dalvik被ART取代),使用Dalvik虚拟机来执行。

Java代码仍然编译成Java字节码,但随后Java字节码会被dex编译器(dx,SDK工具)编译成Dalvik字节码。最终,应用包只包含Dalvik字节码,而不是java字节码。

Android应用也称为apk,因为应用被打包成带有apk后缀的文件,(apk文件只是个简单的ZIP压缩文件,可以使用常见的压缩解压工具如WinZip来查看apk文件的内容)这是一个简单的压缩文件。clasess.dex就在这个压缩文件里,他包含了应用的字节码。Android的工具包中有名为dexdump的工具,可以把classes.dex中的二进制代码转化为使人易读的格式。

------------------------分割线    虚拟机从Dalvik到Art ----------------

JVM和Dalvik工作流程:

JVM和DVM区别:

Java虚拟机Dalvik虚拟机
java虚拟机基于,基于栈的机器必须使用指令来载入和操作栈上数据Dalvik虚拟机基于寄存器
java虚拟机运行的是java字节码。(java类会被编译成一个或多个字节码.class文件,打包到.jar文件中,java虚拟机从相应的.class文件和.jar获取相应的字节码)Dalvik运行的是自己专属的.dex字节码格式。(java类被编译成.class文件后,会通过一个dx工具将所有的.class文件转换成一个.dex文件,然后dalvik虚拟机会从其中读取指令和数据)
-一个应用对应一个Diavik虚拟机实例,独立运行
JVM在运行的时候为每一个类装载字节码Dalvik程序只包含一个.dex文件,这个文件包含了程序中所有的类

Art虚拟机

即Android Runtime,Android 4.4发布了一个ART运行时,准备用来替换掉之前一直使用的Dalvik虚拟机。
ART 的机制与 Dalvik 不同。在Dalvik下,应用每次运行的时候,字节码都需要通过即时编译器(just in time ,JIT)转换为机器码,这会拖慢应用的运行效率,而在ART 环境中,应用在第一次安装的时候,字节码就会预先编译成机器码,使其成为真正的本地应用。这个过程叫做预编译(AOT,Ahead-Of-Time)。这样的话,之后打开App的时候,直接使用本地机器码运行,应用的启动(首次)和执行都会变得更加快速。但是这也意味着会消耗掉更多的存储空间,但消耗掉空间的增幅通常不会超过应用代码包大小的20%。由于有了一个转码的过程,所以应用安装时间难免会延长

Dalvik与Art的区别:

  1. Dalvik每次都要编译再运行,Art只会首次启动编译
  2. Art占用空间比Dalvik大(原生代码占用的存储空间更大),就是用“空间换时间”
  3. Art减少编译,减少了CPU使用频率,使用明显改善电池续航
  4. Art应用启动更快、运行更快、体验更流畅、触感反馈更及时

------------------------分割线    编译器从JIT到AOT----------------

编译器的变迁

Android5.0正式采用 ART之前,Android采用的是解释执行+JIT的方式执行JAVA代码。

Android5.0至Android6.0阶段,Google推出了ART(Android Runtime)来解决之前的JAVA代码执行效率问题。这个阶段采用的是完全AOT模式。这种模式有2个缺点:

    1)APK安装速度巨慢。尤其 系统OTA开机会对所有的应用执行AOT操作,这个时候开机速度可能需要很长时间。

    2)占用磁盘空间,JAVA代码编译为机器码后体积会急剧膨胀。

到了Android7.0,Google做了很大的改进;这一改进基于“我们使用一个应用的时候,基本上只使用了它一小部分功能,为什么把所有代码全编译呢?因此只编译用户经常用的那部分代码就ok了”这样安装的时候速度比较快,等用户启动的时候系统就能知道哪部分代码经常被执行,把这部分代码编译为机器码,运行起来速度也快。

于是Google又引入了JIT,这个时候的执行模式是AOT+JIT+解释执行。    

    1)应用安装时不执行AOT编译,安装速度飞快。

    2)应用运行起来后,系统收集经常被运行的代码的信息,做2件事情:(1)在必要的时候在运行时直接把JAVA代码编译为机器码(JIT),然后使用机器码执行提高运行效率。 (2)把这个【经常被运行的代码信息保存起来】。

    3)设备空闲的时候,系统拿出应用运行时候保存的【热点代码信息】直接把这些代码编译为机器码(AOT)

Android8.0 上改进了解释器,解释模式执行效率大幅提升;Android10.0上提供了预先放置热点代码的方式,应用在安装的时候就能知道常用代码会被提前编译。可以看到,当前Android平台的执行模式在空间占用+安装速度+运行速度上已经到达一个很好的平衡。

总结:目前Android采用的解释执行+还算可以的JIT+AOT的综合模式,但是并没有摆脱这样一个前提:即应用在被打包成APK的时候,采用的还是JAVA代码。换句话说,在APK变成用户可应用的过程中,还经历了一个在Android系统内部的编译过程,这是一个绕不过的坎。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值