为什么基于JVM堆栈和基于DALVIK VM寄存器?
-
01-10-2019 - |
题
我很好奇,为什么Sun决定将基于JVM的堆栈和Google决定制作基于DALVIKVM寄存器?
我想JVM真的不能假设目标平台上有一定数量的寄存器,因为它应该是独立的。因此,它只是将寄存器分配等推迟到JIT编译器。 (如我错了请纠正我。)
因此,Android的家伙想着:“嘿,这是低效的,让我们立即购买基于登记册的VM ...”?但是,等等,有多种不同的Android设备,Dalvik的目标是多少? Dalvik Opcodes是否为一定数量的寄存器进行了硬编码?
市场上所有当前的Android设备是否具有相同数量的寄存器?或者,在DEX加载过程中是否执行寄存器重新分配?这一切如何结合在一起?
解决方案
有一些基于堆栈的VM的属性非常适合Java的设计目标:
基于堆栈的设计对目标硬件(寄存器,CPU功能)做出了很少的假设,因此在各种硬件上实现VM很容易。
由于指令的操作数在很大程度上是隐式的,因此对象代码往往会更小。如果您要通过慢速网络链接下载代码,这很重要。
使用基于寄存器的方案可能意味着Dalvik的代码生成器不必努力工作即可产生性能代码。在极度寄存器或贫困阶段的架构上运行可能会残障Dalvik,但这不是通常的目标 - ARM是一个非常中间的架构。
我还忘记了Dalvik的最初版本根本不包括JIT。如果您要直接解释说明,那么基于寄存器的方案可能是解释绩效的赢家。
其他提示
我找不到参考,但我认为Sun决定采用基于堆栈的字节码方法,因为它可以轻松地在几乎没有寄存器的架构上运行JVM(例如IA32)。
在 Dalvik VM内部 来自Google I/O 2008,Dalvik创建者 丹·伯恩斯坦 给出以下关于在幻灯片35上选择基于寄存器的VM的论点 演示幻灯片:
注册机
为什么?
- 避免使用指令
- 避免不必要的内存访问
- 有效地消耗指令流(通过指令更高的语义密度)
在幻灯片上36:
注册机
统计数据
- 30%的说明减少
- 35%的代码单位少
- 指令流中的字节增加了35%
- 但是我们一次可以消费两次
根据Bornstein的说法,这是“将一组类文件转换为DEX文件时可以找到的一般期望”。
相关部分 演示视频从25:00开始.
还有一篇有见地的纸 Shi等人的“虚拟机摊牌:堆栈与寄存器”。 (2005), ,探索堆栈和基于寄存器的虚拟机之间的差异。
我不知道为什么Sun决定制作基于JVM的堆栈。出于性能原因,erlangs虚拟机,梁是寄存器。由于绩效原因,达维克似乎也是基于注册的。
Dalvik使用寄存器作为数据存储的主要单位而不是堆栈。 Google希望因此能够完成30%的指示。
以及代码大小:
Dalvik VM将生成的Java类文件获取,并将它们组合到一个或多个Dalvik可执行文件(.DEX)文件中。它可以重复从多个类文件中重复的信息,从而有效地将空间要求(未压缩)从传统.JAR文件中降低了一半。例如,Android中的Web浏览器应用程序的.dex文件约为200k,而等效的未压缩.jar版本约为500K。闹钟的.DEX文件约为50k,其.jar版本大约是该大小的两倍。
我记得 计算机架构:定量方法 还得出结论,寄存器的性能要比基于堆栈的机器更好。