Dalvik虚拟机是如何执行程序的

Android层次介绍

Android系统架构采用分层思想,这样可以减少层与层之间的依赖性
Android系统由以下几个部分组成:

  1. 应用程序(APPLICATIONS)
  2. 应用程序框架(APPLICATIONS FRAMEWORK)
  3. Android运行时(ANDROID RUNTIME)
    • 核心库
    • DVM(Dalvik Virtual Machine)
  4. 函数库(LIBRARIES)
  5. Linux内核(LINUX KERNEL)

Dalvik虚拟机是如何执行程序的

Android系统运行过程:
1.加载内核
2.执行init进程,init进程完成设备初始化,然后读取init.rc文件并且启动外部程序Zygote。
3.Zygote进程初始化Dalvik虚拟机,启动system_server并且进入Zygote模式,通过Socket等候命令。
4.当执行一个Android应用程序的时候,system_server进程通过Binder IPC方式发送命令给Zygote,Zygote收到命令之后通过fork自身创建一个Dalvik虚拟机的实例来执行应用程序的入口函数,这样一个程序就启动完成了(每一个应用程序独自占据一个dalvik虚拟机实例)。

执行流程:

Dalvik虚拟机是如何执行程序的

zygote创建进程的方法:

  • fork(),创建一个Zygote进程(这种方式不会被调用,因为只有一个Zygote进程)
  • forkAndSpecialize(),创建一个非Zygote进程
  • forkSystemServer(),创建一个系统服务进程

特点:
zygote进程可以再fork出其他进程
非zygote进程则不能fork出其他进程
system_server进程在终止后他的子进程也必须终止

执行过程:
当进程fork成功之后,执行的工作就交给了Dalvik虚拟机

Dalvik虚拟机首先通过loadClassFromDex()函数完成类的加载工作,每个类被成功解析后都会拥有一个ClassObject类型的的数据结构存储在运行时环境(Android Runtime)中,虚拟机使用gDvm.loadClasses全局哈希表来存储和查询所有装载进来的类

字节码验证器使用dvmVerifyCodeFlow()函数对装入的代码进行校验

接着虚拟机调用FindClass()函数查找并且装载main方法类

随后调用dvmInterpret()函数初始化解释器并且执行字节码流。

Dalvik虚拟机是如何执行程序的

Dalvik虚拟机的JIT
JIT(Just-in-time Compilation,即时编译),又称动态编译,通过在运行时将字节码翻译为机器码的技术,使得程序的运行速度更快。

冷路径和热路径

在函数中代码很少顺序执行,多数代码有很多执行路径。如果有些路径很少被执行,就被称为“冷路径”,如果有些路径经常被执行就被称为“热路径”。

主流的JIT包括两种字节码编译方式
method方式:以函数或者方法为单位进行编译,编译整个方法的代码,在“冷路径”上浪费过多的编译时间。并且耗费更多内存。
trace方式:以trace为单位进行编译,trace方式可以快速获得热路径,使用更短的时间更少的内存来编译代码。