Java 虚拟机与 Dalvik 虚拟机的区别
来源:互联网 发布:电脑课本软件 编辑:程序博客网 时间:2024/06/08 18:05
简述
JVM基于栈架构。
DVM 虚拟机基于寄存器架构(意指由一个指令之输出或输入可以直接索引到的寄存器组群)。
因为实现架构的差异,则DVM对指令的响应要快于 JVM。
代码实践
public class Hello{ public int foo(int a,int b) { return (a+b)*(a-b); } public static void main(String[] args){ Hello hello = new Hello(); System.out.println(hello.foo(5,3)); }}
编写以上代码保存为Hello.java
。打开命令提示符,执行命令javac Hello.java
编译生成Hello.class
文件。
然后执行命令dx --dex --out=Hello.dex Hello.class
。
不幸的是,它抛出异常了,看来是 JDK
的版本问题造成的。
UNEXPECTED TOP-LEVEL EXCEPTION:java.lang.RuntimeException: Exception parsing classes at com.android.dx.command.dexer.Main.processClass(Main.java:752) at com.android.dx.command.dexer.Main.processFileBytes(Main.java:718) at com.android.dx.command.dexer.Main.access$1200(Main.java:85) at com.android.dx.command.dexer.Main$FileBytesConsumer.processFileBytes(Main.java:1645) at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:170) at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:144) at com.android.dx.command.dexer.Main.processOne(Main.java:672) at com.android.dx.command.dexer.Main.processAllFiles(Main.java:574) at com.android.dx.command.dexer.Main.runMonoDex(Main.java:311) at com.android.dx.command.dexer.Main.run(Main.java:277) at com.android.dx.command.dexer.Main.main(Main.java:245) at com.android.dx.command.Main.main(Main.java:106)Caused by: com.android.dx.cf.iface.ParseException: bad class file magic (cafebabe) or version (0034.0000) at com.android.dx.cf.direct.DirectClassFile.parse0(DirectClassFile.java:472) at com.android.dx.cf.direct.DirectClassFile.parse(DirectClassFile.java:406) at com.android.dx.cf.direct.DirectClassFile.parseToInterfacesIfNecessary(DirectClassFile.java:388) at com.android.dx.cf.direct.DirectClassFile.getMagic(DirectClassFile.java:251) at com.android.dx.command.dexer.Main.parseClass(Main.java:764) at com.android.dx.command.dexer.Main.access$1500(Main.java:85) at com.android.dx.command.dexer.Main$ClassParserTask.call(Main.java:1684) at com.android.dx.command.dexer.Main.processClass(Main.java:749) ... 11 more1 error; aborting
$ java -versionjava version "1.8.0_45"Java(TM) SE Runtime Environment (build 1.8.0_45-b14)Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
这里需要把JDK
版本指定为1.6
重新编译Hello.class
。(为什么要更换成1.6
?)
$ javac -source 1.6 -target 1.6 Hello.java
然后执行命令dx --dex --out=Hello.dex Hello.class
。此刻,已经顺利生成了Hello.dex
。
接下来执行
javap -c -classpath . Hello
命令执行后得到如下代码,针对foo()
函数:
// Java 字节码 public int foo(int, int); Code: 0: iload_1 1: iload_2 2: iadd 3: iload_1 4: iload_2 5: isub 6: imul 7: ireturn
接着执行命令:dexdump
可在 sdk/build-tools/
目录下找到。
dexdump -d Hello.dex
生成 Dalvik
字节码如下,针对foo()
函数:
// Dalvik 字节码 000198: |[000198] Hello.foo:(II)I 0001a8: 9000 0304 |0000: add-int v0, v3, v4 0001ac: 9101 0304 |0002: sub-int v1, v3, v4 0001b0: b210 |0004: mul-int/2addr v0, v1 0001b2: 0f00 |0005: return v0
查看上面的 Java 字节码,共8条指令(每条指令占一个字节,并且这些指令都没有参数)。
Q:那么这些指令是如何存取数据的呢?
A:Java 指令集被称为零地址形式的指令集,所谓零地址形式,是指指令的源参数与目标参数都是隐含的,它通过 Java 虚拟机中提供的一种数据结构“求值栈”来传递的。
结合代码来理解理论知识:
(int类型) load
(将局部变量存入 Java 栈) - 1
(局部变量索引) 将第2个 int 类型的局部变量进栈 1:iload_2 1 i load - 2 将第3个 int 类型的局部变量进栈 2:iadd 2 i add 从栈顶弹出两个 int 类型值,将值相加,然后把结果压回栈顶 3:iload_1 3 i load - 1 将第2个 int 类型的局部变量进栈 4:iload_2 4 i load - 2 将第3个 int 类型的局部变量进栈 5:isub 5 i sub 从栈顶弹出两个 int 类型值,将值相减,然后把结果压回栈顶 6:imul 6 i mul 从栈顶弹出两个 int 类型值,将值相乘,然后把结果压回栈顶 7:ireturn 7 i return 返回一个 int 值
所以与之类似的还有lload
,dload
,fload
… 更多信息查看:Java字节码。
Java 虚拟机与 Dalvik 虚拟机的区别
相比 Java 字节码,我们依旧对照代码分析 Dalvik 字节码。
比起 JVM字节码显然 Dalvik字节码更简洁,只有4条指令就完成了上面的工作。
第一条指令 add-int 将 v3与 v4寄存器的值相加,然后保存到 v0寄存器。整个指令的操作中使用到了三个参数,v3、v4分别代表 foo()函数的入参。
第二条指令 sub-int 将 v3减去 v4的值保存到 v1寄存器。
第三条指令 mul-int/2addr 将 v0乘以 v1保存到 v0寄存器。
第四条指令返回 v0寄存器的值。
Dalvik虚拟机运行时同样为每个线程维护一个 PC计数器与调用栈,与 Java 虚拟机不同的是,这个调用栈维护一份寄存器列表,寄存器的数量在方法结构体的 registers 字段中给出,Dalvik 迅疾会根据这个值来创建一份虚拟的寄存器列表。
通过分析得出,基于寄存器架构的 Dalvik 虚拟机与基于栈架构的 Java 虚拟机相比,由于生产的代码指令减少了,程序执行的速度会更快一些。
- Java 虚拟机与 Dalvik 虚拟机的区别
- Dalvik虚拟机与Java虚拟机的区别
- Dalvik虚拟机探析 java虚拟机和Dalvik虚拟机的区别
- java虚拟机和Dalvik虚拟机的区别
- java虚拟机和Dalvik虚拟机的区别
- java虚拟机和Dalvik虚拟机的区别
- java虚拟机和Dalvik虚拟机的区别
- Dalvik虚拟机和Java虚拟机的区别
- Java虚拟机和Dalvik虚拟机的区别
- java虚拟机和Dalvik虚拟机的区别
- java虚拟机和Dalvik虚拟机的区别
- Dalvik虚拟机与java虚拟机的异同
- Dalvik虚拟机与JVM的区别
- Dalvik和标准Java虚拟机的区别
- Dalvik 和 Java 虚拟机的区别
- (Android)java虚拟机和Dalvik虚拟机的区别
- (Android)java虚拟机和Dalvik虚拟机的区别
- (Android)java虚拟机和Dalvik虚拟机的区别
- PAT-A1006 Sign In and Sign Out(25)(模拟)
- sql语句中in后面的数据过多报错,或效率低
- java asm库的原理与使用方法(一)
- 兔子繁殖问题即斐波那契数列的java实现
- [GDKOI2016]染色大战
- Java 虚拟机与 Dalvik 虚拟机的区别
- 【小笔记】afnetworking取数据时输入接口地址
- java.lang.IllegalArgumentException: Page directive: invalid value for import
- Gradle之dependencies
- 分享秦刚老师推荐的《降级论》(罗浩原著),讲了如何跨界
- next_permutation函数
- PAT-A1036 Boys vs Girls(25) (模拟)
- Codeforces Round #259 (Div. 2) A. Little Pony and Crystal Mine
- HDOJ-2052(Picture)