字节码与虚拟机
复习
- 解释器:直接读取程序结构并执行
- 中间表示:与机器无关的通用形式
- 语言运行时:程序运行时的支撑
TL;DR
- 字节码是一种贴近执行、却与具体硬件无关的简化指令
- 虚拟机负责解释执行字节码
- 它比直接解释源码快,又能保持跨平台
- “一次编译,到处运行”正是这个思路
正文
直接解释源码比较慢,因为源码离机器太远。一个折中的办法是:先把源码翻译成一种更接近执行、但又与具体机器无关的形式,再交给一个“虚拟的机器”去跑。这种形式叫字节码(bytecode),执行它的软件叫虚拟机(VM,Virtual Machine)。
字节码:比源码更“贴身”,比机器码更“通用”
字节码的设计,处在一个很舒服的中间位置:
- 它比源码简单、规整:没有复杂的语法,是一条条简单的指令,解释起来快
- 它又比机器码通用:不绑定某个具体的 CPU,任何装了对应虚拟机的地方都能跑
可以说,字节码就是我们前面讲的中间表示,在“执行”场景下的一个分身。
一次编译,到处运行
这带来一个很受欢迎的好处:“一次编译,到处运行”。
程序源码只需要编译成一份字节码,之后在 Windows、Linux、各种机器上,只要有对应的虚拟机,就能执行同一份字节码——不必为每种平台分别编译。 这是把“跨平台”这件事,从“每个平台编译一遍”里抽了出来。
虚拟机的角色
虚拟机是一个用软件模拟出来的“机器”:它认识字节码,逐条解释执行。对使用者来说,就像有一台专门为这门语言打造的、到处都有的虚拟计算机。
它比“直接解释源码”快(因为字节码简单、预处理好),又比“为每台机器静态编译”灵活(因为一份字节码走天下)。当然,它也多了一层:虚拟机本身的解释开销。
所以,字节码 + 虚拟机,是“灵活性”与“效率”之间的又一次折中。但它还能更进一步——下一章的即时编译,会让它在运行时也快起来。
思考题 1
字节码与真正的机器指令,有什么不同?
思考题 2
“一次编译,到处运行”是怎样通过字节码和虚拟机实现的?
小结
知识点
- 字节码是贴近执行、与硬件无关的简化指令
- 虚拟机解释执行字节码
- 它比解释源码快,比静态编译灵活
- 支持“一次编译,到处运行”
参考资料
- Wikipedia(zh):字节码:一种与硬件无关的指令形式
- Wikipedia(zh):虚拟机:用软件模拟的计算机
思考题答案(仅供参考)
思考题 1
真正的机器指令面向某个具体的 CPU,只有该硬件能直接执行;字节码则与具体硬件无关,是一种更简单、更规整的指令,需要由虚拟机来解释执行,因此可以在多种平台上通用。
思考题 2
源码只需编译成一份与平台无关的字节码,再由各平台上对应的虚拟机解释执行。因为字节码不绑定具体硬件,所以这份字节码能在装有虚拟机的不同平台上运行,从而实现“一次编译,到处运行”。
协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
封面图
设计师 | 南国微雪