news 2026/9/4 16:34:32

JVM vs. DVM vs. ART

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JVM vs. DVM vs. ART

JVM vs. DVM 的核心区别

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

JVM 是栈式虚拟机,运算依赖频繁压栈出栈,指令数量多,解释执行时 CPU 取指开销大;DVM 采用虚拟寄存器架构,单条指令可以完成复杂运算,减少指令执行次数,降低 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 被淘汰的重要原因。

32 位寻址上限 4GB,限制 App 使用大内存;64 位放开逻辑限制,程序才有能力去使用大容量物理内存。

  1. 垃圾回收(GC)优化
    • ART 对 GC 进行了改进,堆内存划分更精细,回收效率更高,减少了应用卡顿。

体现

  1. 堆划分更精细
    Dalvik:整个堆一大块。回收经常扫描全部对象,耗时久。 (按来源划分了两个区域, 系统启动类、静态对象、全局只读共享在一个区域(Zygote space), APP 的所有业务对象在 一个区域(Active 堆)。 然后 整个区域 同时做 标记清除。
    一旦堆变大,GC 扫描耗时久,STW 停顿长,碎片严重)
    ART 把 Java 堆分成不同区域:新生代、老年代、大对象区。
    新生代:存放短命临时对象(循环、局部临时对象),回收快、停顿很短
    老年代:长期存活对象(页面数据、全局变量),回收频率低
    大对象单独管理,不用扫描一堆小对象
    小垃圾快速清理,不用每次都扫描整个内存。
  2. 减少长时间 STW(核心优化)
    Dalvik:标记阶段全部暂停。 ART 改成大部分标记工作和 App 线程并发执行(一边跑 App,一边标记垃圾) 只有很短的小段时间需要暂停主线程,GC 停顿时间大幅缩短。
  3. 多线程并行回收
    回收的时候启用多个 CPU 线程一起清理垃圾,加快整体 GC 速度。
  4. 回收策略优化
    新生代使用复制回收,速度快;
    老年代采用并发标记清除;
    更智能的触发时机,尽量不在用户滑动、动画这种关键界面操作时执行重 GC。

JIT 是什么?

JIT 出现之前或尚未触发时,JVM 通过解释器逐条读取和分派字节码,执行解释器内部已有的本地处理逻辑;当方法或循环成为热点后,JIT 会把整段字节码编译成本地机器码,后续直接执行机器码,不再逐条解释。

每条字节码都包含一个opcode,有些指令后面还带操作数。根据 操作码 选择对应处理逻辑的过程,就是指令分派(dispatch)

没有 JIT: 字节码 → 解释器逐条分派 → 本地 handler → CPU 有 JIT: 前期: 字节码 → 解释器 热点后: 字节码 → JIT 编译 → 本地机器码 → CPU 直接执行

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

  • Java 源代码先通过javac编译成.class字节码。
  • 程序刚启动时,解释器逐条解释字节码并执行,因此启动较快。
  • JVM 会统计代码的执行频率。
  • 当某个方法或循环成为热点代码后,JIT 编译器会把它编译成本地机器码。
  • 后续再次执行热点代码时,直接运行机器码,从而提高性能。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/4 16:34:13

zephyr3--外设(TODO)

现在看看如何接外设,我这次用的是Pico2。这次接了一个SPI的屏,还有一个按键。屏幕用的是GC9A01 240x240 圆屏,按键就是普通的IO口按键。1 SPI首先还是配置设备树,在app.overlay。/** GC9A01 240x240 圆屏 Raspberry Pi Pico 2** …

作者头像 李华
网站建设 2026/9/4 16:19:54

用32块矿卡堆出2TB显存,DIY超级计算机跑vLLM推理

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/4 16:19:01

AI创业如何抓住破局点?从YC史上最快独角兽AfterQuery说起

创业圈每隔一段时间就会出现一个让所有人抬头看一眼的名字。这一次,主角是 AfterQuery:一家被传闻以 32 亿美元估值完成新一轮融资的 AI 公司,还背上了一个更醒目的标签——“Y Combinator 史上最快独角兽”。先说结论:这个传闻最…

作者头像 李华
网站建设 2026/9/4 16:18:34

61.吃透 FPGA 高速接口核心!DDR3 协议分析 + RTL 实现 + 上板调试全教程

摘要 本文以FPGA接口设计为主线,从最基础的同步时序模型出发,逐步深入到DDR3 SDRAM控制器接口的完整实现。文章摒弃空洞理论,以一段可直接运行的Verilog代码为核心,详细拆解接口设计的每个环节:时钟域处理、状态机设计、时序约束、读写调度。通过本文,读者将掌握FPGA接口…

作者头像 李华
网站建设 2026/9/4 16:15:13

【单片机课设毕设项目】基于 STM32 或 51 单片机的多参数室内火灾隐患监测装置设计 基于 STM32 或 51 单片机的可参数配置物联网安防监测系统设计(023806)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️…

作者头像 李华