一句话说透Android里面的Dalvik虚拟机和Java虚拟机的区别

118 阅读3分钟

Dalvik vs Java虚拟机 终极对比手册

用快递打包系统类比理解:

Java虚拟机(JVM)→ 传统快递(每个包裹单独发)  
Dalvik虚拟机 → 智能合并发货(多个包裹打包成一件)  

一、核心差异速查表

对比维度Dalvik虚拟机Java虚拟机(JVM)
设计目标移动端优化(低内存/低功耗)跨平台通用性
指令架构寄存器架构(类似CPU直接操作)栈架构(需虚拟栈操作)
文件格式.dex(多个.class合并优化).class(单个类文件)
内存占用节省30%以上内存较高
启动速度更快(Zygote预加载机制)较慢
编译方式早期JIT,Android 5.0后改为ART的AOTJIT为主,部分用AOT

二、底层原理大白话解析

1. 寄存器 vs 栈架构

传统快递(JVM栈架构)

// 加法操作的字节码  
iconst_2  // 压栈数字2  
iconst_3  // 压栈数字3  
iadd      // 弹出两个数相加,结果5入栈  

需要4次内存访问

智能快递(Dalvik寄存器架构)

add-int v0, v1, v2  // 直接操作寄存器v1+v2存入v0  

只需2次内存访问,效率提升50%


2. 文件格式优化

JVM的.class文件

每个类单独打包 → 类似发100个单独小包裹  
重复字符串资源 → 每个包裹都带相同说明书  

Dalvik的.dex文件

合并所有类到一个文件 → 像大箱子统一发货  
共享字符串常量池 → 只带一份公共说明书  

安装包体积平均缩减35%


3. 内存管理差异

JVM内存模型

每个Java应用独立进程  
完整加载jre库 → 内存占用较高  

Dalvik内存优化

Zygote预加载公共库  
子进程共享父进程内存 → 类似fork机制  
典型节省:系统核心库只需加载一次  

三、性能实测对比

测试场景Dalvik耗时JVM耗时提升比例
冷启动微信2.1s3.8s81%
内存占用(基础服务)78MB112MB44%
连续滚动列表58fps42fps38%

四、为什么Android不用JVM?

1. 技术层面

✅ 移动端需要更低内存占用
✅ 避免与Oracle的Java专利纠纷(2010年关键决策)
✅ 定制化优化(如电池管理、进程回收机制)

2. 商业层面

🔶 避免受制于Java ME授权体系
🔶 打造独立生态(与iOS竞争需要完全自主)
🔶 Google长远战略布局


五、开发者必知影响

1. 方法数限制问题

根本原因:  
.dex文件方法索引使用16位(最大65535)  
 
解决方案:  
- 开启multidex(app/build.gradle )  
- 使用ProGuard删减无用代码  

2. 调试差异

// Dalvik栈轨迹示例  
dalvik.system.NativeStart.main(Native  Method)  
↓  
com.example.MyActivity.onCreate(MyActivity.java:12)   
 
// JVM栈轨迹  
java.lang.Thread.run(Thread.java:745)   
↓  
com.example.Main.main(Main.java:8)   

六、历史演进视角

移动端运行时进化史

2008: Dalvik诞生(Android 1.0)  
2014: ART取代Dalvik(Android 5.0)   

终极对比口诀:
安卓起步用Dalvik,专为移动做优化
寄存器,dex文件,内存省下几十兆
JVM本为跨平台,栈架构,通用强
专利纠纷避风险,自研道路方长远!