“概念模型”,是因为实际的虚拟机实现,如HotSpot的模板解释器工作的时候,并不是按照下文中的动作一板一眼地进行机械式计算,而是动态产生每条字节码 对应的汇编代码来运行,这与概念模型中执行过程的差异很大,但结果却能保证是一致的。
解析执行
在Java初生的时候,Java语言经常被定义为“解释执行”的语言,但当主流的虚拟机中都包含了即时编译器后,Class文件中的代码到底是会被解释执行还是编译执行,就只有虚拟机才能准确判断,再后来,Java也发展出可以直接生成本地代码的解释器(如Jaotc、GCJ,Excelsior JET),而C/C++语言也出现了通过解释器执行的版本(如CINT),这时候“解释执行”对于整个Java语言来说就成了几乎没有意义的概念,只有确定了谈论对象时某种具体的Java实现版本和执行引擎运行模式时,谈解释执行还是编译执行才会比较合理确切。
无论是解释还是编译,也无论是物理机还是虚拟机,对于应用程序,机器都不能如人那样阅读、理解,再获得执行能力。大部分程序代码转换成物理机的目标代码或虚拟机能执行的指令集之前,都需要经过如下图的各个步骤:
编译过程.png
如今,基于物理机、Java虚拟机,或者是非Java的其它高级语言虚拟机(HLLVM)的代码执行过程,大体都会遵循这种符合现代经典编译原理的思路,在执行前先对程序源码进行语法分析和语法分析处理,把源码转化为抽象语法树(Abstract Syntax Tree,AST)。
- 对于一门具体语言的实现来说,词法、语法分析以至后面的优化器和目标代码生成器读可以选择独立于执行引擎,形成一个完整意义的编译器去实现,这类代表是C/C++语言。
- 也可以选择把其中一部分步骤(如生成抽象语法树之前的步骤)实现为一个半独立的编译器,这类代表是Java语言。
- 又或者把这些步骤和执行引擎全部集中封装在一个封闭的黑匣子之中,如大多数的JavaScript执行引擎。
在Java语言中,Javac编译器完成了程序代码经过语法分析、语法分析到抽象语法树,再遍历语法树生成线性的字节码指令流的过程。因为这一部分动作是在Java虚拟机之外进行的,而解释器在虚拟机的内部,所以Java程序的编译就是半独立的实现。
《深入理解Java虚拟机》第三版学习
网友评论