虚拟机是什么?

虚拟机概念(virtual machine machine)是一种说明计算机硬件和软件关系的有效方法。

在安德鲁 · 塔嫩鲍姆(Andrew Tanenbaum)的书《结构化计算机组织》(Structured Computer Organization)中可以找到对这个模型广为人知的解释。要说明这个概念,先从计算机的最基本功能开始,即执行程序。

计算机通常可以执行用其原生机器语言编写的程序。这种语言中的每一条指令都简单到可以用相对少量的电子电路来执行。为了简便,称这种语言为 L0。

由于 L0 极其详细,并且只由数字组成,因此,程序员用其编写程序就非常困难。如果能够构造一种较易使用的新语言 L1,那么就可以用 L1 编写程序。有两种实现方法:
  • 解释(Interpretation):运行 L1 程序时,它的每一条指令都由一个用 L0 语言编写的程序进行译码和执行。L1 程序可以立即开始运行,但是在执行之前,必须对每条指令进行译码。
  • 翻译(Translation):由一个专门设计的 L0 程序将整个 L1 程序转换为 L0 程序。然后,得到的 L0 程序就可以直接在计算机硬件上执行。

虚拟机

与只使用语言描述相比,把每一层都想象成有一台假设的计算机或者虚拟机会更容易一些。通俗地说,虚拟机可以定义为一个软件程序,用来模拟一些其他的物理或虚拟计算机的功能。

虚拟机,将其称为 VM1,可以执行 L1 语言编写的指令。虚拟机 VM0 可以执行 L0 语言编写的指令:


每一个虚拟机既可以用硬件构成也可以用软件构成。程序员可以为虚拟机 VM1 编写程序,如果能把 VM1 当作真实计算机予以实现,那么,程序就能直接在这个硬件上执行。否则,用 VM1 写出的程序就被翻译 / 解释为 VM0 程序,并在机器 VM0 上执行。

机器 VM1 与 VM0 之间的差异不能太大,否则,翻译或解释花费的时间就会非常多。如果 VM1 语言对程序员来说还不够友好到足以用于应用程序的开发呢?

可以为此设计另一个更加易于理解的虚拟机 VM2。这个过程能够不断重复,直到虚拟机 VMn 足够支持功能强大、使用方便的语言。

Java 编程语言就是以虚拟机概念为基础的。Java 编译器把用 Java 语言编写的程序翻译为 Java 字节码(Java byte code)。

后者是一种低级语言,能够在运行时由 Java 虚拟机(JVM)程序快速执行。JVM 已经在许多不同的计算机系统上实现了,这使得 Java 程序相对而言独立于系统。

特定的机器

与实际机器和语言相对,用 Level 2 表示 VM2,Level 1 表示 VM1,如下图所示。计算机数字逻辑硬件表示为 Level 1 机器。其上是 Level 2,称为指令集架构(ISA, Instruction Set Architecture) 。通常,这是用户可以编程的第一个层次,尽管这种程序包含的是被称为机器语言的二进制数值。

虚拟机层次结构

指令集架构(Level 2)计算机芯片制造商在处理器内部设计一个指令集来实现基本操作,如传送、加法或乘法。这个指令集也被称为机器语言。每一个机器语言指令或者直接在机器硬件上执行,或者由嵌入到微处理器芯片的程序来执行,该程序被称为微程序。

汇编语言(Level 3)在 ISA 层,编程语言提供了一个翻译层,来实践大规模软件开发。汇编语言出现在 Level 3,使用短助记符,如 ADD、SUB 和 MOV,易于转换到 ISA 层。汇编语言程序在执行之前要全部翻译(汇编)为机器语言。

高级语言(Level 4)Level 4 是高级编程语言,如 C、C++ 和 Java。这些语言程序所包含的语句功能强大,并翻译为多条汇编语言指令。比如,查看 C++ 编译器生成的列表文件输出,就可以看到这样的翻译。汇编语言代码由编译器自动汇编为机器语言。