技术点:
1、JVM,Dalvik与Art三者之间的区别
2、那dex和class到底在结构上有什么区别呢?
3、 JVM基于栈,栈是什么,程序执行的原理是怎么进行的
4、Android 虚拟机中寄存器起什么作用,与栈的区别在哪里
5、Arm指令究竟是什么指令,能说说它与字节码指令的区别吗?
6、为什么Art虚拟机比Dalvik虚拟机运行速度高
7、 Art虚拟机在执行一个含有main函数,堆内存的分布是怎么的
首先,为什么要了解虚拟机?
我觉得主要有以下几点:
1、 对虚拟机运行流程有一个深刻认知,这种认知可以加深APP运行机制的理解
2、 对反编译、热修复、插件化有帮助,我们把dex理解了,能帮助我们理解其中原理
3、 学习这些并不能帮助你对业务上逻辑的理解,但他们能加深你的视野。对原理的掌握反应了你的工作经验
1、JVM,Dalvik与Art三者之间的区别
首先说一下什么是虚拟机:
JVM的作用是把平台无关的.class里面的字节码翻译成平台相关的机器码,来实现跨平台。Dalvik和Art就是安卓中使用的虚拟机
JVM虚拟机与Android虚拟机的区别:
主要体现在编译时JVM与Android 的虚拟机又有些不一样的地方
Art虚拟机与Dalvik虚拟机的区别,以及为什么Art虚拟机比Dalvik虚拟机运行速度高:
Dalvik使用JIT(Just In Time)编译,每次应用在运行时,它实时的将一部分Dalvik.dex生成机器码,它消耗更少的内存,占用的更少的物理存储空间,类似于每次运行代码需要从压缩包取,内存少了,存储少了,CPU消耗相对多了。安装快,启动慢
ART使用AOT(Ahead of Time)编译,ART内置了一个Ahead-Of-Time编译器,在应用安装期间,他就将DEX字节码翻译成机器码并存储在设备的存储器上。这个过程只将应用安装到设备上时发生,由于不再需要JIT编译,代码的执行速度要快很多。安装慢,启动快
预编译也可以明显改善电池续航,因为应用程序每次运行时不用重复编译了,从而减少了CPU的使用频率,降低了能耗
总结:
JVM虚拟机与Android虚拟机的区别:
Android虚拟机执行的是.dex格式文件,jvm执行的是.class文件, class文件存在很多的冗余信息, .dex工具会去除冗余信息,Android虚拟机是寄存器的虚拟机,而JVM是基于虚拟栈的虚拟机。class文件 代表一个类,需要加载多次IO,dex文件里有多个class ,加载一次 IO就可以了。
那Android虚拟机和JVM有什么关系呢?
Android虚拟机是在JVM基础上实现的,只有执行引擎不一样,一个是寄存器结构,一个是栈结构
2、那dex和class到底在结构上有什么区别呢?
总结:
1、 dex文件减少整体的文件尺寸, dex更像是一种压缩文件,一次可以表示更多的class, class是一种单个文件
2、 Android 虚拟机加载类时,只对dex需要一次 IO就可以加载很多类, 而class需要加载多次IO,Android虚拟机提高查找速度
3、 dex指令更加密集,class指令比较多
4、 dex寄存器设计方便寻址, class java栈需要多次load与store指令
5、 dex适合于移动设备, 性能不太高的要求。class适合PC大内存,单指令小的情况下可以快速执行
3、 JVM基于栈,栈是什么,程序执行的原理是怎么进行的
- 那么什么是寄存器,什么是栈呢?
百度百科是这样说:
寄存器的功能是存储二进制代码,它是由具有存储功能的触发器组合起来构成的。一个触发器可以存储1位二进制代码,故存放n位二进制代码的寄存器,需用n个触发器来构成。
栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素
执行原理: JVM执行的时候,指令在局部变量区和栈之间频繁的压栈、出栈。
4、Android 虚拟机中寄存器起什么作用,与栈的区别在哪里
现在实际处理器, 大多都是基于寄存器的架构,从侧面反映出它比基于栈的架构更优秀,一般认为寄存器的架构比JVM架构来说也是更快的
总结:
虽然栈没有地址(无变量声明)指令更紧凑,但完成操作需要更多的load/store指令,也意味着更多的指令分派(instruction dispatch)次数与内存访问次数;访问内存是执行速度的一个重要瓶颈。
Android虚拟机的二地址或三地址指令虽然每条指令占的空间较多,但总体来说可以 用更少的指令完成操作,指令分派与内存访问次数都较少。
Java虚拟机使用的指令只占一个字节,因而成为字节码
。
基于寄存器的指令由于需要指定源地址
和目标地址
,因此需要占用更多的指令空间。
Dalvik虚拟机的某些指令需要占用两个字节。
栈需要更多指令意味着要多占用CPU时间,寄存器需要更多指令空间,意味着数据缓冲(d-cache)更易失效。
5、Arm指令究竟是什么指令,能说说它与字节码指令的区别吗?
字节码指令和Arm指令内容是不一样的
如 同一个 a+b
在JVM的指令 iadd(两int值相加) 、 idiv(两int值相除)、imul(两int值相乘)等
但是在dalvik指令是 add-int 、 mul-int 等
arm指令是由arm公司开发的。指令含有地址,而字节码指令没有地址字节码。
字节码是sun公司开发,简单高效