这是我参与「第四届青训营」笔记创作活动的第9天。
本笔记内容是第八课的Android ART虚拟机。
1 概述
1.1 Android虚拟机的变化
Dalvik:使用解释 + JIT
ART:从Android 4.4开始,到Android 5.0
优化了GC,并引入AOT,在安装时执行
ART:7.0开始
三种执行方式并存。引入了speed profile
1.2 ART整体架构
可分为执行层和运行时。执行层负责处理代码,分为解释器、JIT、AOT等。
运行层提供Java语言机制上的支持,包括内存管理、异常、线程、类管理、JNI、intrinsic、调试、monitor等。
2 对象篇
2.1 对象生命周期中的可关注点
关注对象分配、对象使用、对象销毁。对象分配关注分配大小(类)、内存管理;对象使用关注执行类的方法、访问对象成员。对象销毁后会内存回收,关注GC和清理。
2.2 类管理
类描述对象的内存布局和函数信息。
内存布局指类成员大小、类型、排布方式。
函数信息主要包括虚表的信息,即一个函数定义在当前类函数表的位置。
以上需要全展开继承链后确认。通过继承链可以形成对象的完整内存布局。静态变量跟随classobject。
通过双亲继承,可以保证同一个类的一致性。
2.3 内存分配
可分为TLAB、LOSAllocator、ROSAllocator。三者按次序对比,速度由快到慢,但支持的内存大小由小到大,根据实际情况选用。
内存分配涉及到内存碎片的问题。
内存回收可以分为垃圾回收GC,和引用计数RC。RC引入了弱引用和手动标记的方法来解决无法识别环引用的问题。
强引用:直接持有的引用
软引用:内存不够的时候回收
弱引用:触发GC时回收
ART中前台GC使用tracing GC算法,速度快,会产生内存碎片,不需要额外空间。
后台GC使用copying GC算法,速度慢,无内存碎片,需要额外空间。
3 执行
JIT、AOT会比解释执行效率更高。
JIT可以栈上替换(On-Stack Replacement, OSR)
AOT是在程序运行之前编译APK中的函数,与程序是否运行无关,以dex为单位,其结果持久化。
解释执行和编译执行在栈管理上也有差异,解释执行的压-出栈的速度更慢;解释执行栈结构是托管的,编译执行栈结构遵从虚拟机规则;解释执行传参有额外空间成本,编译执行没有。
不同执行方式的调用切换采用trampoline/bridge进行。
同步机制可分为胖瘦锁。瘦锁需要频繁轮询,但响应快,用spinlock实现。
胖锁则无需频繁轮询,响应慢,用mutexlock实现。
ART虚拟机采用持有状态+检测条件的方式实现胖瘦锁切换。
4 总结
本节课主要学习到ART虚拟机的基础知识,ART虚拟机作为Android正在使用的虚拟机,是有必要深入了解的。本节课为深入了解虚拟机提供方向。以后的学习中需要了解更多此类知识,可以阅读老师推荐的《深入理解Android:Java虚拟机ART》、《虚拟机设计与实现:以JVM为例》,还可以阅读技术文章。