目录

  1. 概述
  2. Java 代码编译和执行的整个过程
  3. Java 源码编译机制
  4. 类加载机制
  5. 虚拟机栈上操作
  6. 附录

概述

Java 程序运行时,必须经过编译运行两个步骤。

  1. 首先前端编译将后缀名为.java 的源文件进行编译,最终生成后缀名为.class 的字节码文件。
  2. 然后 Java 虚拟机将编译好的字节码文件加载到内存(这个过程被称为类加载,是由加载器完成的),然后虚拟机针对加载到内存的 java 类进行解释执行,显示结果。

Java 代码编译和执行的整个过程

Java 代码编译是由 Java 编译器来完成,具体细节如下:

Java 字节码的执行是由 JVM 执行引擎来完成 ,流程图如下所示:

Java 代码编译和执行的整个过程包含以下三个重要的机制:类加载机制、类执行机制和 Java 源代码编译机制

Java 源码编译机制

Java 源代码编译主要由以下三个过程组成:分析符号表、注解处理以及语义分析和生成 class 文件。

最终生成的 class 文件由以下部分组成:

  1. 结构信息。包括 class 文件格式版本号及各部分的数量与大小的信息
  2. 元数据。对应于 Java 源码中声明与常量的信息。包含类/继承的超类/实现的接口的声明信息、域与方法声明信息和常量池
  3. 方法信息。对应 Java 源码中语句和表达式对应的信息。包含字节码、异常处理器表、操作数栈与局部变量区大小、操作数栈的类型记录、调试符号信息

类加载机制

通过前端编译之后生成了 class 文件,随后就是需要通过响应的类加载器,将 .class 文件装载到系统中,关于类加载的细节并不在这里展示。

虚拟机栈上操作

JVM 是基于栈的体系结构来执行 class 字节码的。所以,线程创建后,都会产生程序计数器和栈,程序计数器存放下一条要执行的指令在方法内的偏移量,栈中存放一个个栈帧,每个栈帧对应着每个方法的每个方法调用。栈帧又是由局部变量区和操作数栈两部分组成,局部变量表用于存放方法中的局部变量和参数,操作数栈中用于存放方法执行过程中产生的中间结果。

由于 JAVA 都有一个 main() 方法,作为程序的启动方法。所以,程序执行的第一步就是将对应的main()方法装载进虚拟机栈中执行,然后根据主函数的需要,再分配不同的栈帧到虚拟栈中.通过最简单的程序稍加验证。

1
2
3
4
5
public class TestP {
public static void main(String[] args) {
System.out.println("1");//在此行打上断点
}
}

通过 debug 运行,可以在 idea 上看见如下的程序虚拟机栈

附录

java 程序是如何执行的?