问题起因:
我注意到再写java程序运行时不会像.exe程序一样出现在windows的任务管理器---进程一栏里面,只能看到javaw.exe。(可以了解一下javaw.exe与java.exe区别)然后经过一系列联想我就到了一个问题:java的.class文件由虚拟机的解释器解释为机器码,这个机器码是给JVM执行的机器码,还是类似于.exe给操作系统执行的机器码。
于是我把这个问题丢到群里面,大家都会有一个观点:这个机器码是给java虚拟机用的。也就是说java代码执行的大致流程为:
假设1:
1.我们手写的.java文件;
2.javac编译后的.class文件;
3.java虚拟机里面的类加载器加载.class文件;
4.字节码解释器将.class文件解释成java虚拟机能执行的机器码(这里面会有类,对象等概览);
5.虚拟机通过执行机器码逻辑和调用系统硬件服务(也就是说java的所有底层硬件服务都由JVM代劳与操作系统交付);
6.程序运行。
这样好像能走通,但是如果机器码是在JVM上执行,那还保留.class文件干嘛,直接机器码和JVM就可以快平台了。而且是这个逻辑的话,想想JVM的实现应该就不是一件很难的事了。
还有我们常常能看到这样的描述,教科书上也是这样的描述:
、
也就是说,java最终产生的机器码是运行于操作系统上的,平台有关的机器码,这与我上面流程的第4步明显不符,再做出第二种假设:
2.javac编译后的.class文件;
3.java虚拟机里面的类加载器加载.class文件,初始化JVM的堆、栈;
4.java虚拟机里面的解释器将JVM堆、栈里面的数据解释为机器码;
6.操作系统执行机器码,这个过程脱离了;
7.程序运行。2.javac编译后的.class文件;
3.java虚拟机里面的类加载器加载.class文件,初始化JVM的堆、栈、程序计数器等;
4.java虚拟机开始执行加载的.class文件,读取JVM堆、栈的方法指令、变量、参数到JVM的程序计数器准备执行解释;
5.java虚拟机里面的解释器将程序计数器里面的指令、数据解释成操作系统能执行的机器码;
6.操作系统执行机器码,并将结果返回给JVM;
7.程序运行。