JVM运行流程
Java 虚拟机(Java Virtual Machine,JVM)是 Java 平台的核心组件之一,它是一个在实际硬件和操作系统上模拟运行 Java 字节码的虚拟计算机
Java 程序被执行的顺序通常包括以下几个步骤:
-
编辑(Edit):程序员编写 Java 源代码文件(.java 文件),其中包含类、方法、变量等定义。
-
编译(Compile):使用 Java 编译器(javac)将源代码文件编译成字节码文件(.class 文件)。编译过程将源代码文件转换为平台无关的字节码。
-
加载(Load):Java 虚拟机(JVM)加载字节码文件到内存中,并对字节码进行验证、准备和解析等操作。
-
链接(Link):在链接阶段,JVM 将字节码文件中的符号引用转换为直接引用,并生成可执行代码。链接包括三个子阶段:
- 验证(Verification):确保字节码文件符合 Java 虚拟机规范,防止恶意代码和错误代码对系统造成损害。
- 准备(Preparation):为类的静态变量分配内存空间,并设置默认初始值。
- 解析(Resolution):将符号引用转换为直接引用,即将类、方法、字段等在内存中的地址解析出来。
-
初始化(Initialization):在初始化阶段,JVM 执行类的初始化代码,对静态变量赋初值,并执行静态代码块。初始化阶段是类加载过程中的最后一个阶段,只有在初始化之后,类才能被真正使用。
-
执行(Execution):JVM 执行程序的主方法(main() 方法),从 main() 方法开始执行程序的主要逻辑。程序的执行顺序由代码中的逻辑和控制流程决定,可以包括方法调用、条件语句、循环结构等。
以上是 Java 程序执行的一般顺序,每个步骤都是逐步进行的,直到程序完全执行结束。
GC
垃圾回收(Garbage Collection,GC)是 Java 虚拟机(JVM)自动管理内存的重要功能,它负责在运行时识别和清除不再使用的对象,以释放内存空间。以下是 GC 的核心知识点:
-
对象的生命周期:了解对象的生命周期是理解 GC 的基础。当一个对象被创建后,它会被分配在堆内存中。当对象不再被引用时,它变成了不可达对象,这时候就可以被垃圾回收器识别和回收。
-
引用类型:在 Java 中,对象之间的引用可以分为强引用、软引用、弱引用和虚引用等几种类型。不同类型的引用影响着对象的生命周期和垃圾回收行为。
-
垃圾回收算法:垃圾回收器使用不同的算法来识别和回收内存中的不再使用的对象。常见的算法包括标记-清除算法、复制算法、标记-整理算法和分代收集算法等。
-
垃圾回收器:Java 虚拟机中有多种垃圾回收器,如串行回收器、并行回收器、并发回收器和 G1 回收器等。不同的回收器适用于不同的场景和需求,可以通过 JVM 参数进行配置和选择。
-
GC 日志分析:GC 日志记录了垃圾回收器的执行情况,包括回收的对象数量、回收时间、停顿时间等信息。通过分析 GC 日志可以了解程序的内存使用情况和垃圾回收性能,进而优化程序的内存管理和性能。
-
调优策略:根据实际场景和需求,需要选择合适的垃圾回收器和调优策略。常见的调优手段包括调整堆大小、选择合适的垃圾回收器、减少对象的创建和引用、优化程序逻辑等。
以上是 GC 的核心知识点,理解这些知识可以帮助开发者更好地理解 Java 内存管理机制,优化程序的性能和内存利用率。
在 Java 虚拟机中,堆内存(Heap)被划分为不同的区域,其中包括新生代(Young Generation)、老年代(Old Generation)等。这些区域主要用于管理对象的生命周期和执行垃圾回收。以下是对新生代和老年代的介绍:
-
新生代(Young Generation):
- 新生代是堆内存的一部分,用于存放新创建的对象。
- 新生代通常被进一步划分为 Eden 区和两个 Survivor 区(From 和 To 区)。
- 大多数对象首先分配在 Eden 区,当 Eden 区满时,会触发 Minor GC,将存活的对象移动到 Survivor 区。
- Survivor 区用于存放经过一次或多次 Minor GC 后仍然存活的对象。在多次 Minor GC 过程中,存活的对象会从一个 Survivor 区移动到另一个 Survivor 区,直到最终被移动到老年代或被回收。
-
老年代(Old Generation):
- 老年代用于存放长期存活的对象和从新生代晋升过来的对象。
- 当一个对象经过多次 Minor GC 后仍然存活,它会被晋升到老年代。
- 当老年代的空间不足时,会触发 Full GC(Major GC 或 Full Garbage Collection),对整个堆进行垃圾回收。
- Full GC 的触发频率相对较低,因为它会导致停顿时间较长,影响程序的性能。
新生代和老年代的划分使得 Java 垃圾回收更加高效,因为大部分对象的生命周期较短,很快就会被回收,而只有少部分对象会进入老年代,减少了 Full GC 的频率。优化堆内存的分配和垃圾回收策略,可以提高 Java 程序的性能和稳定性。