什么是Java虚拟机?
要弄明白Java程序的执行过程首先要了解一下Java虚拟机
虚拟机是一种抽象化的计算机,通过在实际的计算机上仿真模拟各种计算机功能来实现的。Java虚拟机有自己完善的硬体架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。Java虚拟机屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。
Java虚拟机(Java Virtual Machine简称JVM)是运行所有Java程序的抽象计算机,是Java语言的运行环境,它是Java 最具吸引力的特性之一。--百度百科
可以看到,Java虚拟机是在原有计算机的基础上虚拟出来的抽象计算机,提供Java程序的运行环境。JVM屏蔽了与具体操作系统平台相关的信息,使得Java程序只需要生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。JVM是Java平台无关的基础,使Java程序能够做到 “Write Once, Run Anywhere”。
Java程序执行过程
那有了Java程序的运行环境等一些列支持后,Java程序是如何做到从一个只有代码的.java源文件变成计算机可执行的文件的呢? 如下图,是Java程序的执行过程。
大致过程就是,我们写好的.java文件(源文件)被编译器编译后变成.class文件(字节码),然后被JVM的类加载器加载到内存,通过字节码校验器去做一些校验,校验通过后交由解释器将字节码文件解释成计算机能够识别的机器指令。
维基百科
字节码:字节码是已经经过编译,但与特定机器码无关,需要解释器转译后才能成为机器码的中间代码。
Java字节码:是Java虚拟机执行的一种指令格式。
解释器:是一种电脑程序,能够把高级编程语言一行一行直接翻译运行。解释器不会一次把整个程序翻译出来,只像一位“中间人”,每次运行程序时都要先转成另一种语言再作运行,因此解释器的程序运行速度比较缓慢。它每翻译一行程序叙述就立刻运行,然后再翻译下一行,再运行,如此不停地进行下去。它会先将源码翻译成另一种语言,以供多次运行而无需再经编译。其制成品无需依赖编译器而运行,程序运行速度比较快
通过上图我们知道Java程序的执行会经过一下几个步骤:编译-->装载字节码-->校验字节码-->解释字节码-->执行,然后我们看一下这几个步骤具体执行过程,以及Java程序的执行过程对应到我们的实际操作:
1、编译
在windows环境中,打开命令窗口,切换到java文件的目录,使用 javac 命令,执行 javac xxx.java 把.java文件编译成.class文件
2、装载字节码
编译好的.class文件交给 JVM 执行,即使用java命令,执行java xxx(.class文件的名称,不带后缀)。java命令将会启动 JVM,并将后面的参数作为初始化类,通过 JVM 内的类加载器将字节码文件装载到内存中。
3、校验字节码
类的加载是通过类加载器进行的,加载完后,先由字节码校验器负责检查那些无法执行的明显有破坏性的操作。除了系统类之外,其他类都要被校验。
校验器执行的一些检查:
- 变量要在使用前初始化
- 方法调用与对象引用类型之间要匹配
- 访问私有数据和方法的规则没有被违反
- 对本地变量的访问都在运行的堆栈内
- 运行时堆栈没有溢出
如果这些检查没有通过,类最终不会被加载完成。
4、解释字节码
JVM 把每一条要执行的字节码交给解释器,翻译成对应的机器语言,最终由操作系统执行。
JVM解释执行字节码文件就是JVM操作Java解释器进行解释执行字节码文件的过程。
维基百科
机器语言:机器语言(machine language)是一种指令集的体系。这种指令集称为机器代码(machine code),是计算机的CPU可直接解读的数据。
结语
实际上JVM执行字节码文件远比这复杂,其中还包括即时编译器、指令重排等优化。这里只是对Java程序的执行过程做一个大致的介绍,让Java程序员能够明白自己写的程序在JVM里到底是如何执行的。如果要深入研究JVM的更多细节,建议大家去看书或其他资料。