【学习笔记】关于jvm与android平台的虚拟机_fileeeeeee的博客-爱代码爱编程
运行时数据区就是字节码运行时在内存中的状态
方法区:用于存放字节码中加载出来的类信息
堆:用于存放实例类型的数据,JVM垃圾回收主要针对于堆
虚拟机栈
记录线程内方法的执行状态
栈帧
栈中的元素,对应每一个方法的执行情况
fun main(){
foo()
...
}
fun foo(){
val a = 1
val b = 2
val c = (a+b)*9
}
操作数栈:字节码执行时处理中间状态的内存区域
基于栈的JVM
0行:int类型的1推送至栈顶
1行:将栈顶数据存入第一个本地变量 (此时局部变量a赋值为1)
2行:int类型的2推送至栈顶
3行:将栈顶数据存入第二个本地变量(此时局部变量b赋值为2)
4、5行:将对应的局部变量的值入栈,从局部变量表拿回操作数栈
6行:将栈顶两个数相加,并将结果压入栈顶
7行:将单字节常量放入栈顶,占用两个单元,所以下一行跳到9
9行:将栈顶两个int数值相乘,并将结果压入栈顶
a行:将栈顶数据存入第三个本地变量(此时局部变量c赋值为27)
b行:return
Dalvik虚拟寄存器
0行:将1存入指定寄存器中 v0=1
1行:将2存入指定寄存器中 v1=2
2行:将两个寄存器执行二元运算相加,并将结果存入第一个寄存器中。v0=3
3行:执行二元运算相乘,并将结果存入。v0=27
编译优化:以使用最少寄存器为前提,不改变语意义,优化掉无用代码
各自特点:
基于栈的JVM字节码单元长度为8位(1字节),Dalvik为16位(2字节)
单条指令长度较短,而Dalvik几乎翻倍
同样逻辑指令条数较多,Dalvik较少
同样逻辑数据移动次数较多,Dalvik尽可能少
同样逻辑临时结果存储次数较多,Dalvik尽可能少
如何看待基于栈的虚拟机设计?
1. JVM基于栈去设计的初衷之一,是压缩代码体积
a. Java设计之初最重要的一个特性就是跨平台,支持嵌入式设备和手持设备(J2ME)
b. 另一个特性是支持远程传输执行字节码,要降低传输开销
2. 基于栈的虚拟机,字节码实现简单
a. 指的是生成字节码的过程简单,而不是虚拟机本身简单,或者说是编译器的简单实现
b. 操作时,不用考虑寄存器的地址,只需要把想要操作的数据出栈、入栈,然后在实现如何针对栈进行操作
3. 可移植性高
a. 为了提高效率,虚拟寄存器要映射到真实机器的寄存器,增加移植难度
b. 代码移植到其他硬件平台的时候,不用考虑真实机器寄存器的差异,因为操作栈的指令是通用的
如何看待Android平台基于寄存器的设计?
1. 更快,更省内存
a. 指令条数少
b. 数据移动次数少、临时结果存放次数少
c. 映射到真实机器的寄存器
2. Android不需要解决移植性问题
3. 用其他方式解决了代码体积问题
a. dex文件优化