JVM vs. DVM vs. ART

JVM vs. DVM 的核心区别

  1. 基于的架构不同
  • JVM基于栈,需要去栈中读写数据,所需的指令更多,导致速度变慢,对于性能有限的移动设备不是很适合
  • DVM 基于寄存器, 指令紧凑,更简洁,可以减少指令分派、取指和解释执行的次数,降低CUP开销,因此更适合移动设备有限的CPU和内存环境

解释器执行每条字节码时,都需要经过取指、解码、分派和执行。取指是读取下一条字节码,分派是根据操作码跳转到对应的处理逻辑,解释执行则是由解释器完成该指令表示的操作。寄存器型字节码通常用更少的指令完成相同任务,因此可以减少解释器循环和指令分派次数,这在以解释执行为主的早期移动设备上有一定性能优势。

  1. 执行的字节码不同
  • JVM 会从 .class 文件 或 打包的 .jar 文件 中获取相应的字节码。
    每个 .class 文件里面包含了该类的常量池、类信息、属性等。当JVM加载 .jar 文件的时候,会加载里面的所有的 .class 文件,JVM 的这种方式很慢,对内存有限的移动设备不适合。
  • DVM 会从 .dex 文件 读取指令和数据。
    .apk 文件中只包含了一个 .dex 文件,这个 .dex 文件会将所有的 .class 里面包含的信息全部整合在一起,并且 dex 工具会去除很多 .class 文件的冗余信息,将 .class 文件整合到 .dex 文件中, 减少了 I/O 操作,加快了类的查找速度。
  1. DVM 早期没有使用 JIT 编译器
    JVM 使用了 JIT 编译器(Just In Time Compiler,即时编译器),而 DVM 早期没有使用 JIT 编译器。
    早期的 DVM 每次执行代码,都需要通过解释器将 dex 代码编译成机器码,然后交给系统处理,效率不是很高。
    为了解决该问题,后期,DVM 使用了 JIT 编译器,它会对多次运行的代码(热点代码)进行编译,生成相当精简的本地机器码(Native Code),这样在下次执行到相同逻辑的时候,直接使用编译之后的本地机器码,而不是每次都需要编译。

Dalvik 与 ART 的核心区别

  1. 编译方式不同(核心)

    • Dalvik :采用 JIT(即时编译),每次运行应用时,字节码实时编译为机器码,程序运行效率低。(本质上还是解释执行,边解释边执行)
    • ART :默认采用 AOT(预编译),安装时一次性将字节码编译为本地机器码,运行流畅、省电,但安装耗时、占用空间大。
    • Android 7.0+ 混合模式:ART 加入 JIT 作为补充,安装时不将字节码全编译为机器码,运行时识别编译热点代码为机器码,平衡安装速度、空间和运行性能。
  2. CPU 架构支持

    • Dalvik 仅支持 32 位 CPU;
    • ART 支持 64 位且兼容 32 位,是 Dalvik 被淘汰的重要原因。
  3. 垃圾回收(GC)优化

    • ART 对 GC 进行了改进,堆内存划分更精细,回收效率更高,减少了应用卡顿。

JIT 是什么?

JIT 出现之前或尚未触发时,JVM 通过解释器逐条读取和分派字节码,执行解释器内部已有的本地处理逻辑;当方法或循环成为热点后,JIT 会把整段字节码编译成本地机器码,后续直接执行机器码,不再逐条解释。
每条字节码都包含一个 opcode ,有些指令后面还带操作数。根据 操作码 选择对应处理逻辑的过程,就是 指令分派(dispatch)

text 复制代码
没有 JIT:

字节码
→ 解释器逐条分派
→ 本地 handler
→ CPU


有 JIT:

前期:
字节码
→ 解释器

热点后:
字节码
→ JIT 编译
→ 本地机器码
→ CPU 直接执行

"解释执行 + JIT 编译"的混合模式

  • Java 源代码先通过 javac 编译成 .class 字节码。
  • 程序刚启动时,解释器逐条解释字节码并执行,因此启动较快。
  • JVM 会统计代码的执行频率。
  • 当某个方法或循环成为热点代码后,JIT 编译器会把它编译成本地机器码。
  • 后续再次执行热点代码时,直接运行机器码,从而提高性能。
相关推荐
名字还没想好☜2 小时前
Java 线上内存泄漏排查实战:jmap 导堆、MAT 找 GC Roots 与四类常见泄漏
java·开发语言·jvm·内存泄漏
淡海水10 小时前
01-07-运行时-GC深度剖析-内存分配回收与结构选择
jvm·windows·unity·gc
2602_9599609212 小时前
电商大厂Java面试:从Spring Boot、JPA、微服务到Redis、Kafka、Spring Security与监控,谢飞机的爆笑三轮问答
java·jvm·spring boot·redis·面试题
一水13 小时前
AI 时代审查思维:审查第一篇
java·jvm·数据库·spring
それども21 小时前
JVM MetaspaceSize 参数作用
jvm
java_upp1 天前
JVM内存溢出和内存泄漏的区别及排查方法
jvm·内存泄漏·内存溢出
城管不管2 天前
MySQL 慢查询完整排查
java·服务器·jvm·数据库·mysql·spring·面试
mister_guo2 天前
JVM 内存管理原理及生产配置实战:从“参数能启动”到“内存可控”
java·jvm
名字还没想好☜3 天前
Go 的 strings.Builder 实战:拼接性能、Grow 预分配与何时该用 bytes.Buffer
java·jvm·后端·golang·go
wear工程师4 天前
Java 类初始化到底何时触发?别把加载、连接和 static 执行混在一起
java·jvm