目录
程序计数器(Program Counter Register)
Java语言的跨平台特性
Java语言具有跨平台特性,这意味着可以编写一次Java代码,并在不同的操作系统和硬件平台上运行,而无需进行大量的修改或重新编译。
- Java虚拟机(Java Virtual Machine):Java程序在运行时被编译为字节码(bytecode),而不是特定于某个平台的机器代码。字节码可以在任何支持Java虚拟机的平台上运行,因此Java程序可以在Windows、Mac、Linux等各种操作系统上执行。
- Write Once, Run Anywhere(一次编写,到处运行):通过Java的跨平台特性,可以编写一次Java代码,然后在不同的平台上运行。只需将编译后的字节码文件(.class文件)拷贝到目标平台,并确保目标平台上有合适版本的Java虚拟机,就可以在该平台上运行程序。
- 平台无关的标准库:Java提供了丰富的标准库,涵盖了各种常用功能和API。这些库是与平台无关的,因此可以在任何支持Java虚拟机的平台上使用。
- 自动内存管理:Java通过垃圾回收器(Garbage Collector)自动管理内存,开发人员无需手动分配和释放内存。这有助于减少与特定平台相关的内存管理问题。
- 安全性:Java具有内置的安全机制,可以防止恶意代码对系统的损害。Java的安全性模型包括类加载器、安全管理器和沙箱环境,可以确保代码在不同平台上以安全的方式运行。
JVM 的主要组成部分及其作用是什么?
1、类加载器(Class Loader):类加载器负责将字节码文件(.class文件)加载到内存中,并将其转换为可执行的Java类,并在运行时动态链接这些类。它根据类的全限定名查找和加载字节码文件,并生成类的运行时数据结构,供JVM使用。
它分为三个主要的层次:
- Bootstrap Class Loader
- Application Class Loader
- Extension Class Loader
2、执行引擎(Execution Engine):执行引擎负责解释和执行Java字节码指令。它将字节码转换为可执行的机器指令,并执行这些指令。
它包含两个主要的部分:
- 解释器(Interpreter):逐行解释执行字节码指令,实现跨平台的特性,但执行速度相对较慢。
- 即时编译器(Just-In-Time Compiler,JIT):将字节码转换为本地机器码,这样可以在后续的执行中直接运行本地机器码,提高执行速度。
3、运行时数据区(Runtime Data Area):运行时数据区是JVM中的内存区域,用于存储各种数据和程序运行时所需的数据。主要包括方法区、堆、栈、程序计数器和本地方法栈等。
- 方法区(Method Area):方法区用于存储类的结构信息、常量、静态变量和字节码等。它是被所有线程共享的内存区域。
- 垃圾回收器(Garbage Collector):垃圾回收器负责自动回收不再被使用的对象,并释放它们占用的内存空间。它通过检测和标记不可达对象,并回收它们的内存,以供后续的对象分配使用。
- 本地方法栈(Native Method Stack):本地方法栈用于执行本地方法(Native Method)。本地方法是使用其他编程语言(如C、C++)编写的方法,通过Java本地接口(JNI)与Java代码进行交互。
- 本地接口(Native Interface):允许Java代码调用本地库中的方法,也允许本地库调用Java代码。这样可以在Java中使用其他语言编写的库,实现与底层系统的交互。
- 程序计数器(Program Counter Register):程序计数器用于存储当前线程正在执行的字节码指令的地址或索引。它在方法调用、执行和返回过程中发挥重要作用。
- 栈(Stack):栈用于管理方法的调用和执行过程。每个线程在执行时都会有一个栈,用于存储局部变量、方法调用、返回信息和操作数栈等。
- 堆(Heap):堆用于存储对象实例和数组。在Java中,所有通过new关键字创建的对象都存储在堆上,堆是Java动态分配内存的主要区域。也是垃圾回收的主要区域。
JVM的主要作用是提供一个可移植、安全和高性能的运行环境,使得Java程序可以在不同的操作系统和硬件平台上运行。它负责加载、解释和执行Java字节码,提供内存管理和垃圾回收、线程管理、异常处理、安全检查等功能。JVM的设计和实现使得Java具备了跨平台性、可移植性和安全性的优势。
JVM整体结构及内存模型
线程栈(Machine Stack)
每个线程在执行时都有自己的线程栈,线程栈独立于其他线程,互不共享。
线程栈的主要作用如下:
- 方法调用和执行:线程栈用于管理方法的调用和执行过程。每当一个方法被调用时,JVM会在线程栈上创建一个新的栈帧(Stack Frame),栈帧用于存储方法的参数、局部变量和中间结果。方法执行期间,栈帧会保持在栈顶,直到方法执行完毕。
- 局部变量存储:线程栈用于存储方法的局部变量。每个方法在执行时,会分配一定的栈空间用于存储方法的参数和局部变量。局部变量包括方法的参数和方法内部声明的变量,它们的生命周期仅限于方法的执行期间。
- 递归调用支持:线程栈支持方法的递归调用。当一个方法在执行过程中调用自身或其他方法时,每次调用都会在线程栈上创建一个