运行Java程序后,都发生了什么?
大家好呀,今天我们又开始了Java基础的学习之旅啦!上篇文章《javac 命令-详解》,我们认识了javac命令并能熟练运用,我们知道了如何编译一个java源程序,编译之后会在javac源文件同目录下生成一个.class 字节码文件。这个编译好之后的字节码文件就为我们之后的工作做了准备。
准备工作
- 使用编辑器编写一个java源代码,我这里使用的notepad++编辑器,编写一个“B.java”java源程序。
- 打开DOS窗口进入要编译的java源文件的目录下,输入“javac B.java” ,回车。
- 编译好的“B.class”文件在同目录下被生成。
- 运行字节码文件:在DOS窗口输入“java B”,回车。
- 内容在控制台上输出。
示意图
分析
上述中,当我们敲入 java B 回车 之后,我们的 B.class 字节码文件都发生了什么?
当一个字节码文件在Java命令执行之后运行时,涉及到两个主要方面的过程:加载和执行。这两个方面分别属于Java虚拟机(JVM)的不同阶段。下面是这两个方面的过程的总结:
加载阶段:
- 启动JVM:
在命令行中使用java
命令运行已编译的字节码文件时,JVM会被启动。 - 类加载器:
JVM启动后,它会通过类加载器加载您指定的主类(包含public static void main(String[] args)
方法)。类加载器在类路径(classpath)上查找字节码文件(.class
文件)。 - 加载字节码:
类加载器将找到的字节码文件加载到内存中,并在内存中创建类的表示。这些类的信息存储在方法区(Metaspace)中。
执行阶段:
- 解释执行字节码:
加载类后,JVM会解释执行其中的字节码指令。这些指令是Java源代码编译而成的中间表示,JVM逐条解释执行这些指令。 - 即时编译(可选):
在程序运行过程中,JIT编译器可能会识别频繁执行的热点代码。它会将这些代码块编译成本地机器代码,以提高执行速度。这些本地机器代码被存储在代码缓存中。 - 本地机器代码执行:
即时编译器生成的本地机器代码在程序的后续执行阶段中被执行。这些本地机器代码更接近硬件,因此执行速度更快。 - 与操作系统和硬件交互:
在程序执行过程中,JVM可能需要与操作系统进行交互,例如进行内存管理、I/O操作等。JVM通过调用操作系统提供的接口来实现这些功能。 - 程序结束:
一旦主类的main
方法执行完毕,程序会结束运行。JVM可以正常退出,也可以通过调用System.exit()
来强制退出。
总结
在java
命令执行之后,一个字节码文件会被JVM加载并解释执行其字节码指令。如果有热点代码,JIT编译器可能会将其编译成本地机器代码。在执行过程中,JVM与操作系统和硬件交互,执行各种任务。最终,程序执行完毕,JVM可能会退出。这个过程允许Java实现"一次编写,到处运行"的特性,因为JVM在不同的平台上提供了统一的运行环境。
该文章收录在《java基础》专栏里,我会持续更新,希望同学们可以积极学习!