首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
01 | Java代码是怎么运行的?
02 | Java的基本类型
03 | Java虚拟机是如何加载Java类的?
04 | JVM是如何执行方法调用的?(上)
05 | JVM是如何执行方法调用的?(下)
06 | JVM是如何处理异常的?
07 | JVM是如何实现反射的?
08 | JVM是怎么实现invokedynamic的?(上)
09 | JVM是怎么实现invokedynamic的?(下)
10 | Java对象的内存布局
11 | 垃圾回收(上)
12 | 垃圾回收(下)
13 | Java内存模型
14 | Java虚拟机是怎么实现synchronized的?
15 | Java语法糖与Java编译器
16 | 即时编译(上)
17 | 即时编译(下)
18 | 即时编译器的中间表达形式
19 | Java字节码(基础篇)
20 | 方法内联(上)
21 | 方法内联(下)
22 | HotSpot虚拟机的intrinsic
23 | 逃逸分析
24 | 字段访问相关优化
25 | 循环优化
26 | 向量化
27 | 注解处理器
28 | 基准测试框架JMH(上)
29 | 基准测试框架JMH(下)
30 | Java虚拟机的监控及诊断工具(命令行篇)
31 | Java虚拟机的监控及诊断工具(GUI篇)
32 | JNI的运行机制
33 | Java Agent与字节码注入
34 | Graal:用Java编译Java
35 | Truffle:语言实现框架
36 | SubstrateVM:AOT编译框架
当前位置:
首页>>
技术小册>>
深入拆解 Java 虚拟机
小册名称:深入拆解 Java 虚拟机
### 01 | Java代码是怎么运行的? 在深入探讨Java虚拟机(JVM)的奥秘之前,理解Java代码是如何从编写到执行的全过程是至关重要的。这一过程不仅涉及Java语言的特性,还紧密关联着JVM作为Java程序运行环境的核心角色。本章将详细解析Java代码的运行机制,从源代码的编写、编译、加载到执行,逐步揭开Java“一次编写,到处运行”(Write Once, Run Anywhere, WORA)理念的实现面纱。 #### 一、Java程序的编写与编译 **1.1 Java程序的编写** Java程序的开发始于源代码的编写。Java源代码是以`.java`为扩展名的文本文件,其中包含了使用Java语言编写的类、接口、方法等。Java语法清晰简洁,遵循面向对象编程的原则,支持自动内存管理和垃圾回收机制,极大地简化了开发者的工作。 开发者使用文本编辑器或集成开发环境(IDE)如Eclipse、IntelliJ IDEA等编写Java源代码。这些工具提供了代码高亮、自动补全、错误检查等功能,提高了编程效率和代码质量。 **1.2 Java编译器(javac)** 编写完成的Java源代码需要通过Java编译器(javac)转换成Java字节码(Bytecode)。字节码是一种介于源代码和机器码之间的中间代码,它既不是针对特定机器的机器码,也不是源代码的直接翻译,而是为JVM设计的指令集。这一转换过程称为编译,是Java实现跨平台运行的关键步骤。 编译过程中,javac会检查源代码中的语法错误、类型错误等,并生成相应的错误和警告信息。如果编译成功,则会产生以`.class`为扩展名的字节码文件,每个`.java`源文件对应至少一个`.class`文件(如果存在内部类或匿名类,则会产生更多)。 #### 二、Java字节码与类加载机制 **2.1 Java字节码简介** Java字节码是一种平台无关的二进制格式,它包含了一组JVM能够识别的指令和操作数。这些指令定义了程序的行为,如变量赋值、方法调用、循环控制等。由于字节码不依赖于任何具体的硬件或操作系统,因此Java程序可以在任何安装了JVM的平台上运行。 **2.2 类加载机制** Java程序运行时,JVM通过类加载机制将字节码文件加载到内存中,并转换为JVM内部的数据结构,以便执行。类加载机制是JVM的核心组成部分之一,它负责动态地加载、连接和初始化类及其资源。 类加载过程大致可以分为三个主要阶段:加载(Loading)、连接(Linking)、初始化(Initialization)。 - **加载**:JVM通过类加载器(ClassLoader)查找并读取字节码文件,将其内容加载到JVM的方法区中,并创建一个代表该类的`java.lang.Class`对象,作为访问类元数据的入口。 - **连接**:包括验证(Verification)、准备(Preparation)和解析(Resolution)三个子阶段。验证确保字节码符合JVM规范;准备为类的静态变量分配内存并设置默认值;解析将符号引用替换为直接引用,即解析出具体的内存地址。 - **初始化**:执行类的初始化代码,即执行`<clinit>()`方法,该方法由编译器自动收集类中所有类变量的赋值操作和静态语句块中的语句合并而成。 类加载器采用双亲委派模型(Parent Delegation Model),即当需要加载一个类时,首先会尝试由父类加载器加载,如果父类加载器无法加载,则再由子类加载器尝试加载。这种模型确保了Java核心库的类型安全,避免了类的重复加载。 #### 三、Java虚拟机与运行时数据区 **3.1 Java虚拟机概述** Java虚拟机是一个可以执行Java字节码的虚拟计算机,它定义了Java程序的运行环境。JVM负责解释执行字节码,管理内存,提供垃圾回收机制等。不同的操作系统上可以有不同的JVM实现,但只要遵循JVM规范,就可以保证Java程序的跨平台性。 **3.2 运行时数据区** JVM在执行Java程序时,会在内存中划分出几个不同的区域来存储不同类型的数据,这些区域统称为运行时数据区(Runtime Data Areas),主要包括: - **方法区**:存储每个类的结构信息,如运行时常量池(Runtime Constant Pool)、字段和方法数据、构造函数和普通方法的字节码内容等。这部分内存是全局共享的,在一定条件下可以被垃圾回收。 - **堆(Heap)**:所有对象实例以及数组的内存分配都在堆上进行,堆是垃圾收集器管理的主要区域,因此也被称为“GC堆”。堆可以细分为新生代(Young Generation)和老年代(Old Generation),新生代进一步划分为Eden区、两个Survivor区(From和To)。 - **栈(Stack)**:每个线程都有自己的栈,用于存储局部变量和部分中间结果,每个方法被调用时都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。 - **程序计数器(Program Counter Register)**:一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器。字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令。 - **本地方法栈(Native Method Stacks)**:与虚拟机栈所发挥的作用非常相似,它们之间的区别不过是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的Native方法服务。 #### 四、Java代码的执行 **4.1 字节码的执行** Java字节码的执行是由JVM的解释器(Interpreter)和即时编译器(Just-In-Time Compiler, JIT Compiler)共同完成的。解释器逐条解释执行字节码指令,速度较慢但启动迅速;JIT编译器则将热点代码(频繁执行的代码)编译成机器码,直接由CPU执行,以提高执行效率。 **4.2 垃圾回收机制** Java堆是垃圾收集器管理的主要区域,垃圾收集器会对堆内存进行扫描,识别出不再被程序使用的对象,并回收其占用的内存空间。Java提供了多种垃圾收集算法和垃圾收集器,如标记-清除(Mark-Sweep)、复制(Copying)、标记-整理(Mark-Compact)、分代收集(Generational Collection)等,以适应不同的应用场景和性能需求。 **4.3 线程与并发** Java支持多线程编程,JVM内部包含了一个或多个线程管理器来管理线程的创建、调度和销毁。Java提供了丰富的线程同步机制,如synchronized关键字、Lock接口、volatile关键字、CAS(Compare-And-Swap)操作等,以保证多线程环境下的数据一致性和线程安全。 #### 五、总结 Java代码的运行是一个复杂而精妙的过程,它涉及源代码的编写、编译、加载、执行等多个阶段。JVM作为Java程序的运行环境,通过类加载机制、运行时数据区管理、字节码执行、垃圾回收机制等关键技术,实现了Java程序的跨平台性和高效运行。理解Java代码的运行机制,对于深入掌握Java语言、优化程序性能、解决复杂问题具有重要意义。希望本章内容能够帮助读者揭开Java程序运行的神秘面纱,为进一步学习JVM和Java技术打下坚实的基础。
下一篇:
02 | Java的基本类型
该分类下的相关小册推荐:
Mybatis合辑3-Mybatis动态SQL
Java必知必会-Maven高级
Java必知必会-Maven初级
Java语言基础6-面向对象高级
SpringBoot合辑-高级篇
经典设计模式Java版
Java语言基础8-Java多线程
Java并发编程实战
Java语言基础9-常用API和常见算法
Mybatis合辑5-注解、扩展、SQL构建
Java并发编程
手把手带你学习SpringBoot-零基础到实战