一、Java从编译到执行
1. Java程序运行过程
如图所示,我们的Java代码需要通过javac编译成.class后缀的字节码文件,然后才能被JVM执行。在JVM中,首先需要通过类加载器加载这个字节码文件,然后由字节码解释器去解析字节码文件,最后由执行引擎去基于解析后的指令去操作OS硬件系统。
2. 什么是JIT(Just In Time Compiler)?
当虚拟机发现某个方法或代码块的运行特别频繁的时候,就会把这些代码认定为“热点代码”。为了提高热点代码的执行效率,在运行时,即时编译器JIT会把这些代码编译成与本地平台相关的机器码,并进行各种层次的优化。
3. 解释器和编译器各自的优点
解释器的优点:当程序需要迅速启动的时候,解释器可以首先发挥作用,省去了编译的时间,立即执行。解释执行占用更小的内存空间。同时,当编译器进行的激进优化失败的时候,还可以进行逆优化来恢复到解释执行的状态。
编译器的优点:在程序运行时,随着时间的推移,编译器逐渐发挥作用,把越来越多的代码编译成本地代码之后,可以获得更高的执行效率。
结论:通常在虚拟机的架构中,解释器与编译器通常会配合工作,提升效率。
二、JVM跨平台和语言无关性
1. JVM的跨平台
JVM如何做到的跨平台?
Java官方提供了各个平台32bit和64bit的机器的不同版本的JDK,所以在各个平台下都会有相应的JVM。站在JVM的角度,JVM只解释执行字节码文件,所以我们的Java代码会统一会编译成字节码文件,这样就可以在各个平台上运行了。
简而言之,也就是Java官方从包揽了各个平台下JVM的开发工作,程序员不需要考虑平台各自的接口和特性,只需要提供编译后的class字节码文件,这样就可以一处编译处处运行,达到平台无关性(Write Once ,Run Anywhere)。
2. JVM的语言无关性
JVM只解释执行字节码文件,所以无论语言是什么样,只要最终可以编译成字节码文件,这样的代码就可以在JVM上运行。
截至目前,商业机构和开源机构已经在Java语言之外发展出一大批可以在JVM上运行的语言了,如Groovy、Scala、Jython等。之所以可以支持,就是因为这些语言也可以被编译成字节码(.class文件),而虚拟机并不关心字节码是有哪种语言编译而来的。