JVM内存管理深度剖析
https://blog.csdn.net/qq_44076155/article/details/110676870
深入理解对象与垃圾回收机制
https://blog.csdn.net/qq_44076155/article/details/110676774
Android虚拟机与classLoader类加载机制
Dalvik/ART 虚拟机
DVM(Dalvik virtual machine) 也是实现了JVM规范的一个虚拟器,默认使用CMS垃圾回收器,但是与JVM运行 Class 字节码不同,DVM执行 Dex(Dalvik Executable Format)** ——专为 Dalvik 设计的一种压缩格式。Dex 文件是很多 .class 文件处理压缩后的产物,最终可以在 Android 运行时环境执行。
而
ART
(
Android Runtime
) 是在 Android 4.4 中引入的一个开发者选项,也是 Android 5.0 及更高版本的默认
Android 运行时。ART 和 Dalvik 都是运行 Dex 字节码的兼容运行时,因此针对 Dalvik 开发的应用也能在 ART 环
境中运作。
Dalvik和ART虚拟机是基于寄存器的虚拟机,而JVM是基于栈的虚拟机
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字节码的文件。
解释执行: 需要一个解释器,它会将我们的一句句解释成机器代码来执行,可以认为是,解释一句,执行一句。在这个过程中,不会生成中间文件。
编译执行 : 先编译再执行,这里需要有一个编译器,来将我们的代码全部编译成机器代码,然后进行执行。因为先整体进行编译,所以这里会生成编译后的机器代码。
在Android7前,ART使用预先编译机制,在安装时,ART 使用设备自带的 dex2oat 工具来编译应用,dex中的字节码将被编译成本地机器码。这样会造成安装时间过长
Android7后,1、最初安装应用时不进行任何 AOT 编译(安装又快了),运行过程中解释执行,对经常执行的方法进行JIT,经过 JIT 编译的方法将会记录到Profile配置文件中。 2、当设备闲置和充电时,编译守护进程会运行,根据Profile文件对常用代码进行 AOT 编译。待下次运行时直接使用。
ClassLoader(类加载器)
任何一个
Java
程序都是由一个或多个
class
文件组成,在程序运行时,需要将
class
文件加载到
JVM
中才可以使
用,负责加载这些
class
文件的就是
Java
的类加载机制。
ClassLoader
的作用简单来说就是加载
class
文件,提供
给程序运行时使用。每个
Class
对象的内部都有一个
classLoader
字段来标识自己是由哪个
ClassLoader
加载的。
ClassLoader是一个抽象类,有BootClassLoader和BaseDexClassLoader两个子类
而BaseDexClassLoader有PathClassLoader和DexClassLoader两个子类
我们重点关注BootClassLoader和PathClassLoader两个类
BootClassLoader用于加载Android Framework层class文件(系统类)
PathClassLoader用于Android应用程序类加载(用户的类,包括第三方框架的类)
加载一个类
ClassLoader类中有一个ClassLoader类型的parent变量,
这个
parent
的目的就在于实现类加载的双
亲委托
1.首先判断缓存中是否存在该类,如果有则返回该类
2.判断parent是否为空,不为空则调用parent加载该类
3.parent没找到,自己去找这个类
双亲委托机制
某个类加载器在接到加载类的请求时,首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成类
加载任务,就成功返回;只有父类加载器无法完成此加载任务时,才自己去加载。
优点
在启动程序时,系统会事先为我们创建一个PathClassLoader,传入的ClassLoader参数为BootClassLoader
结合上面加载类的流程,当我们使用PathClassLoader加载类时,当缓存中未找到时,会先调用BootClassLoader的loadclass,如果BootClassLoader找不到再轮到PathClassLoader找。
findClass
在所有父
ClassLoader
无法加载
Class
时,则会调用自己的
findClass
方法。
先看看pathList的实现,pathList是一个DexPathList对象
spliteDexpath把dex切成一个一个dexElement对象,然后存入List
dexpath是dex文件的地址,每有一个dex文件则创建一个dexElement对象
进入到pathList.findClass,遍历dexList数组,找到每一个dex中的class对象
流程图解
基于上面的类加载方式进行热修复
基础热修复实现原理 反射