1.基于栈的虚拟机
JVM式基于栈的虚拟机
2.基于寄存器的虚拟机
寄存器是CPU的组成部分,寄存器是有限存储容量的高速存储部件,他们可以用来暂存指令、数据和位置
Dalvik是基于寄存器的虚拟机
3.Art与Dalvik的区别
Dalvik虚拟机执行的是dex字节码,解释执行。从Android 2.2版本开始,支持JIT即时编译(Just In Time)在程序运行的过程中进行选择热点代码(经常执行的代码)进行编译或者优化。
ART(Android Runtime) 是在 Android 4.4 中引入的一个开发者选项,也是 Android 5.0 及更高版本的默认 Android 运行时。ART虚拟机执行的是本地机器码。Android的运行时从Dalvik虚拟机替换成ART虚拟机,并不要求开发者将自己的应用直接编译成目标机器码,APK仍然是一个包含dex字节码的文件。
-
ART虚拟机执行的本地机器码是从哪里来?
Dalvik下应用在安装的过程,会执行一次优化,将dex字节码进行优化生成odex文件。而Art下将应用的dex字节码翻译成本地机器码的最恰当AOT时机也就发生在应用安装的时候。ART 引入了预先编译机制(Ahead Of Time),在安装时,ART 使用设备自带的 dex2oat 工具来编译应用,dex中的字节码将被编译成本地机器码。
4.Android N Art虚拟机的混合模式
ART 使用预先 (AOT) 编译,并且从 Android N混合使用AOT编译,解释和JIT。
1、最初安装应用时不进行任何 AOT 编译(安装又快了),运行过程中解释执行,对经常执行的方法进行JIT,经过 JIT 编译的方法将会记录到Profile配置文件中。
2、当设备闲置和充电时,编译守护进程会运行,根据Profile文件对常用代码进行 AOT 编译。待下次运行时直接使用。
5.Android中各个ClassLoader的作用
- BootClassLoader 用于加载Android Framework层的class文件,比如: String.class Activity.class
- PathClassLoader Android应用程序类的加载器,可以加载指定的dex,以及jar、zip、apk中的classes.dex.比如:我们自己写的类
Log.e(TAG, "Activity.class 由:" + Activity.class.getClassLoader() +" 加载");
Log.e(TAG, "MainActivity.class 由:" + getClassLoader() +" 加载");
//输出:
Activity.class 由:java.lang.BootClassLoader@d3052a9 加载
MainActivity.class 由:dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.enjoy.enjoyfix-1/base.apk"],nativeLibraryDirectories= [/data/app/com.enjoy.enjoyfix-1/lib/x86, /system/lib, /vendor/lib]]] 加载
6.ClassLoader加载类流程与双亲委托机制
某个类加载器在加载类时,首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成类加载任务,就成功返回;只有父类加载器无法完成此加载任务或者没有父类加载器时,才自己去加载。
- 双亲委托机制作用
1、避免重复加载,当父加载器已经加载了该类的时候,就没有必要子ClassLoader再加载一次。
2、安全性考虑,防止核心API库被随意篡改。(避免加载到自己写的系统类)
7.安卓类加载从APK(dex)加载类的流程
8.dex插桩式热修复原理
- 热修复流程
1 获取到当前应用的PathClassLoader
2 反射获取到DexPathList属性对象的pathList
3.反射修改pathList的dexElements
把补丁包的patch.dex转化为Elements
获得pathList的dexElements属性(old)
path+old合并,并反射复制给pathList的dexElements
生成dex文件命令
dx --dex --output=output.dex input.jar