JVM
Java虚拟机就是二进制字节码的运行环境,负责装载字节码到其内部,解释/编译为对应平台上的机器指令执行。每一条Java指令,Java虚拟机规范中都有详细定义,如怎么取操作数,怎么处理操作数,处理结果放在哪里。
特点:
- 一次编译,到处运行
- 自动内存管理
- 自动垃圾回收功能
JVM的位置
JVM是运行在操作系统之上的,它与硬件没有直接的交互
JVM整体结构
Java虚拟机(JVM)是一个包含多个组件的运行时环境。其核心组件包括类加载子系统、运行时数据区、执行引擎、本地接口和本地方法库。类加载子系统负责加载Java类,而运行时数据区包括方法区和堆,堆又分为新生代和老年代。执行引擎负责解释和执行Java字节码,同时具备即时编译器提高性能。本地接口允许Java代码与本地代码进行交互,而本地方法库包含与底层操作系统相关的本地方法。这些组件协同工作,使得Java程序能够在不同平台上高效运行。
- **Class Loader Subsystem(类加载子系统)**
- Bootstrap Class Loader
- Extension Class Loader
- Application Class Loader
- **Runtime Data Area(运行时数据区)**
- **Method Area(方法区)**
- **Heap(堆)**
- New Generation(新生代)
- Eden Space(伊甸区)
- Survivor Spaces (S0, S1)(幸存者区)
- Old Generation(老年代)
- PermGen / Metaspace(永久代 / 元空间)
- **Execution Engine(执行引擎)**
- **Interpreter(解释器)**
- **Just-In-Time (JIT) Compiler(即时编译器)**
- **Garbage Collector(垃圾收集器)**
- **Native Interface(本地接口)**
- Native Method Interface(本地方法接口)
- **Native Method Libraries(本地方法库)**
Java代码执行流程
Java 源码编写
开发人员使用 Java 编写源代码,这些源代码以
.java
为扩展名。
Java 编译器(javac)
使用 Java 编译器 (
javac
) 将源代码编译成字节码文件(以.class
为扩展名)。这个阶段生成的字节码文件包含了 Java 字节码指令,是与平台无关的中间代码。
类加载器
类加载器负责加载字节码文件到内存中,形成类的运行时数据结构。Java 的类加载器体系通常包括启动类加载器、扩展类加载器和应用程序类加载器。
字节码验证器:
字节码验证器确保字节码符合 Java 虚拟机规范,防止恶意代码和错误。验证包括类型检查、访问权限检查、代码转换检查等。
字节码解释执行或JIT编译:
执行引擎负责将字节码指令解释执行或者通过即时编译器(JIT 编译器)将字节码编译成本地机器码,以提高执行效率。JIT 编译器将热点代码(经常执行的代码)编译成本地机器码,加速程序的执行。
运行时数据区
在运行时数据区中,包括方法区、堆、虚拟机栈、本地方法栈、程序计数器等。这些区域用于存储程序的状态、方法的运行时信息、对象实例等。
本地方法调用
如果 Java 代码中包含了本地方法调用(
native
关键字),则调用本地方法接口(JNI)与本地方法库进行连接。本地方法接口负责将 Java 数据类型转换为本地方法支持的数据类型,并调用本地方法库中的函数。
本地方法库:
本地方法库是由本地语言(如 C 或 C++)编写的库,其中包含与 Java 代码进行交互的本地方法的实现。当执行引擎调用本地方法时,实际的执行是在本地方法库中完成的。
操作系统
Java 虚拟机与操作系统交互,使用操作系统提供的服务和资源。这可能包括文件系统、网络、线程管理等。
最终执行
Java 程序的最终执行是通过执行引擎执行字节码指令,从而按照程序的逻辑改变程序状态,包括对栈、堆和方法区的操作。整个过程中,涉及到了类加载、字节码验证、执行引擎执行、本地方法调用等多个组成部分。