一个Java的main方法在JVM中的执行流程示例详解

2025-09-24 00:50

本文主要是介绍一个Java的main方法在JVM中的执行流程示例详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《一个Java的main方法在JVM中的执行流程示例详解》main方法是Java程序的入口点,程序从这里开始执行,:本文主要介绍一个Java的main方法在JVM中执行流程的相关资料,文中通过代码...

一个Javamain方法在JVM中的执行流程可以分为​​四大阶段​​:​​加载 -> 链接 -> 初始化 -> 执行​​。

// HelloWorld.java
public class HelloWorld {
    public static void main(String[] args) {
        String message = "Hello, JVM!";
        System.out.println(message);
    }
}

第一阶段:加载 (Loading)

​目标:找到并加载类的二进制数据。​

1.​​编译​​:你执行 javac HelloWorld.java。Java编译器将源代码编译成JVM能理解的字节码,存储在 HelloWorld.class文件中。这个文件包含了一个​​类常量池(Constant Pool)​​,里面有各种符号引用,比如 Hello, JVM!这个字符串的字面量、System/out/println等类名、方法名和字段名。

2.​​启动JVM​​:你执行 java HelloWorld操作系统会启动JVM进程

3.​​寻找类​​:JVM通过​​类加载器(ClassLoader)​​ 来加载 HelloWorld类。

 Bootstrap ClassLoader​​:首先,启动类加载器会去加载JAVA_HOME/lib下的核心类库,如 java.lang包(包括ObjectStringSystem等)。

• Application ClassLoader​​:然后,应用程序类加载器开始工作,它在你的CLASSPATH(默认是当前目录)下寻找 HelloWorld.class文件。

4.​​创建Class对象​​:JVM成功读取 HelloWorld.class的二进制字节流后,会将其转换为​​方法区(MetASPace)​​ 中的运行时数据结构,并同时在 ​​Java堆(Heap)​​ 中创建一个 java.lang.Class对象,作为方法区这些数据的访问入口。这个 Class对象封装了类的所有元信息(如方法、字段等)。

第二阶段:链接 (Linking)

​目python标:将加载到方法区的二进制数据合并到JVM运行时状态中。​javascript此阶段细分为三步:

1.​​验证 (Verification)​​:JVM会严格检查 HelloWorld.class文件的格式、元数据、字节码等是否符合规范且不会危害JVM自身安全。这是一个非常重要的安全屏障。

2.​​准备 (Preparation)​​:JVM为​​类的静态变量(static variables)​​ 在方法区分配内存并设置​​初始值​​(零值)。注意,这里是初始值,不是代码中赋的值。

•例如,如果类里有 static int value = 123;,在准备阶段,value会被赋值为 0。真正的赋值 123要等到后面的初始化阶段。

3.解析 (Resolution)​​:JVM将​​类常量池​​中的​​符号引用(Symbolic References)​​ 替换为​​直接引用(Direct References)​​。

符号引用​​:就是一种约定好的形式来表示引用的目标,比如 java/lang/System.out

直接引用​​:就是一个直接指向目标的指针、偏移量或句柄。

•例如,在这一步,System.out这个符号引用会被解析为 java.io.PrintStream对象在堆内存中的实际地址。

第三阶段:初始化 (Initialization)

​目标:执行类的构造器 <clinit>()方法,为静态变量赋予程序设定的初始值。​

1.到了这一步,JVM才开始真正执行你写在Java代码中的静态语句和静态变量赋值。

2.JVM会收集类中的所有​​静态变量的赋值动作​​和​​静态代码块(static {})​​,合并生成一个唯一的 <clinit>()方法。

3.JVM会确保 <clinit>()方法在多线程环境下被正确地加锁同步执行,所以类初始化是线程安全的。

4.在我们的 HelloWorld例子中,没有静态变量和静态代码块,所以 <clinit>()方法是空的,但这一步依然会发生。

第四阶段:执行 (Execution & Runtime)

​目标:创建线程,执行字节码。​

1 . 主线程​​:JVM会为 main方法创建一个​​主线程​​。该线程拥有自己的​​程序计数器(PC)​​ 和 ​​Java虚拟机栈(JVM Stack)​​。

2 .​​ 栈帧​​:线程的每个方法调用都会在虚拟机栈中创建一个​​栈帧(Stack Frame)​​,用于存储​​局部变量表​​、​​操作数栈​​、​动态链接​​、​​方法返回地址​​等信息。main方法是程序入口,所以第一个被压入栈的栈帧就是 main方法的栈帧。

3 .​ ​执行引擎​​:JVM的​​执行引擎​​开始解释执行 main方法栈帧中的字节码。

String message = "Hello, JVM!";

执行引擎遇到字面量 "编程;Hello, JVM!"时,会去​​字符串常量池(String Table,位于堆中)​​ 中寻找。DcrecaTyZ如果找不到,就在堆中创建一个String对象并将其引用驻留在常量池中,然后将该引用存入 main栈帧的局部变量表 message中。

System.out.println(message);

执行引擎通过之前在​​解析阶段​​已经转换好的​​直接引用​​,快速地找到 System.out对应的 PrintStream对象。

然后调用该对象的&www.chinasem.cnnbsp;println方法,将局部变量 message的引用(指向堆中的String对象)作为参数传入。

4 .​​ 本地方法调用​​:println方法底层是一个​​本地方法(Native Method)​​,调用的是操作系统本身的IO能力,将字符串输出到控制台。

5 .​​ 方法返回​​:main方法执行完毕,其栈帧从虚拟机栈中弹出。主线程结束。

6 .​​ JVM退出​​:所有​​非守护线程​​都结束后,JVM进程终止。

总结

到此这篇关于一个Java的main方法在JVM中执行流程的文章就介绍到这了,更多相关JVM中main方法执行流程内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程China编程(www.chinasem.cn)!

这篇关于一个Java的main方法在JVM中的执行流程示例详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1155999

相关文章

java读取excel文件为base64实现方式

《java读取excel文件为base64实现方式》文章介绍使用ApachePOI和EasyExcel处理Excel文件并转换为Base64的方法,强调EasyExcel适合大文件且内存占用低,需注意... 目录使用 Apache POI 读取 Excel 并转换为 Base64使用 EasyExcel 处

java时区时间转为UTC的代码示例和详细解释

《java时区时间转为UTC的代码示例和详细解释》作为一名经验丰富的开发者,我经常被问到如何将Java中的时间转换为UTC时间,:本文主要介绍java时区时间转为UTC的代码示例和详细解释,文中通... 目录前言步骤一:导入必要的Java包步骤二:获取指定时区的时间步骤三:将指定时区的时间转换为UTC时间步

Java 日志中 Marker 的使用示例详解

《Java日志中Marker的使用示例详解》Marker是SLF4J(以及Logback、Log4j2)提供的一个接口,它本质上是一个命名对象,你可以把它想象成一个可以附加到日志语句上的标签或戳... 目录什么是Marker?为什么使用Markejavascriptr?1. 精细化的过滤2. 触发特定操作3

深入浅出Java中的Happens-Before核心规则

《深入浅出Java中的Happens-Before核心规则》本文解析Java内存模型中的Happens-Before原则,解释其定义、核心规则及实际应用,帮助理解多线程可见性与有序性问题,掌握并发编程... 目录前言一、Happens-Before是什么?为什么需要它?1.1 从一个问题说起1.2 Haht

Python实现简单封装网络请求的示例详解

《Python实现简单封装网络请求的示例详解》这篇文章主要为大家详细介绍了Python实现简单封装网络请求的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录安装依赖核心功能说明1. 类与方法概览2.NetHelper类初始化参数3.ApiResponse类属性与方法使用实

JDK8(Java Development kit)的安装与配置全过程

《JDK8(JavaDevelopmentkit)的安装与配置全过程》文章简要介绍了Java的核心特点(如跨平台、JVM机制)及JDK/JRE的区别,重点讲解了如何通过配置环境变量(PATH和JA... 目录Java特点JDKJREJDK的下载,安装配置环境变量总结Java特点说起 Java,大家肯定都

Linux中查看操作系统及其版本信息的多种方法

《Linux中查看操作系统及其版本信息的多种方法》在服务器运维或者部署系统中,经常需要确认服务器的系统版本、cpu信息等,在Linux系统中,有多种方法可以查看操作系统及其版本信息,以下是一些常用的方... 目录1. lsb_pythonrelease 命令2. /etc/os-release 文件3. h

python语言中的常用容器(集合)示例详解

《python语言中的常用容器(集合)示例详解》Python集合是一种无序且不重复的数据容器,它可以存储任意类型的对象,包括数字、字符串、元组等,下面:本文主要介绍python语言中常用容器(集合... 目录1.核心内置容器1. 列表2. 元组3. 集合4. 冻结集合5. 字典2.collections模块

Spring定时任务之fixedRateString的实现示例

《Spring定时任务之fixedRateString的实现示例》本文主要介绍了Spring定时任务之fixedRateString的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有... 目录从毫秒到 Duration:为何要改变?核心:Java.time.Duration.parse

Java 中 Optional 的用法及最佳实践

《Java中Optional的用法及最佳实践》在Java开发中,空指针异常(NullPointerException)是开发者最常遇到的问题之一,本篇文章将详细讲解Optional的用法、常用方... 目录前言1. 什么是 Optional?主要特性:2. Optional 的基本用法2.1 创建 Opti