JVM的生命周期

目录

  • 引言
    • [1. 虚拟机的启动](#1. 虚拟机的启动)
      • [1.1 引导类加载器](#1.1 引导类加载器)
      • [1.2 初始化步骤](#1.2 初始化步骤)
    • [2. 虚拟机的执行](#2. 虚拟机的执行)
      • [2.1 主要任务](#2.1 主要任务)
      • [2.2 运行时数据区](#2.2 运行时数据区)
      • [2.3 垃圾收集](#2.3 垃圾收集)
        • [2.3.1 标记-清除算法](#2.3.1 标记-清除算法)
        • [2.3.2 复制算法](#2.3.2 复制算法)
        • [2.3.3 标记-整理算法](#2.3.3 标记-整理算法)
        • [2.3.4 分代收集](#2.3.4 分代收集)
    • [3. 虚拟机的退出](#3. 虚拟机的退出)
      • [3.1 正常退出](#3.1 正常退出)
      • [3.2 异常退出](#3.2 异常退出)
      • [3.3 其他退出方式](#3.3 其他退出方式)
      • [3.4 关闭钩子](#3.4 关闭钩子)
    • [4. 结论](#4. 结论)

引言

Java虚拟机(JVM)是Java应用程序运行的核心,它负责加载、验证、准备、解析和初始化Java类,并执行其字节码。理解JVM的生命周期对于优化程序性能、解决内存问题以及进行故障排除至关重要。本文将深入探讨JVM的启动、执行和退出过程。

1. 虚拟机的启动

1.1 引导类加载器

Java虚拟机的启动是通过引导类加载器 (bootstrap class loader)创建一个初始类 (initial class)来完成的,这个类是由虚拟机的具体实现指定的。引导类加载器通常使用C/C++编写,嵌套在JVM内部,主要负责加载核心Java类库,如java.lang.Object等基础类。

1.2 初始化步骤

  • 配置JVM装载环境 :JVM需要找到并加载相关的动态链接库文件,例如jvm.dll
  • 解析虚拟机参数:处理命令行参数,例如设置堆大小等。
  • 设置线程栈大小:为每个线程分配默认的栈大小。
  • 执行Java main方法 :最后,JVM会找到并执行指定的主类中的main方法。

2. 虚拟机的执行

2.1 主要任务

一个运行中的Java虚拟机有着一个清晰的任务:执行Java程序。当程序开始执行时,JVM才开始运行;当程序结束时,JVM也随之停止。实际上,执行所谓的Java程序时,真正执行的是一个叫做Java虚拟机的进程。

2.2 运行时数据区

JVM的运行时数据区主要包括以下几个部分:

  • 堆(Heap):存储对象实例(在Java中,new出来的都是存放在堆中),是垃圾回收的主要场所。
  • 方法区(Method Area):存放已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
  • 虚拟机栈(VM Stack):每个线程拥有自己的虚拟机栈,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。
  • 本地方法栈(Native Method Stack):与虚拟机栈类似,但为Native方法服务。
  • 程序计数器(Program Counter Register):记录当前线程所执行的字节码指令地址。

2.3 垃圾收集

JVM提供自动内存管理,即垃圾收集机制,以释放不再使用的对象所占用的内存。常见的垃圾收集算法包括标记-清除、复制、标记-整理等。常用的垃圾收集器有Serial、Parallel、CMS和G1等。

2.3.1 标记-清除算法
  • 标记:遍历对象图,标记所有可达对象。
  • 清除:清理未被标记的对象,释放空间。
2.3.2 复制算法
  • 划分内存:将可用内存划分为两部分。
  • 复制存活对象:将存活对象从一部分复制到另一部分,然后清空原部分的空间。
2.3.3 标记-整理算法
  • 标记:同标记-清除算法。
  • 整理:将存活对象向一端移动,然后清理边界以外的内存。
2.3.4 分代收集
  • 新生代:采用复制算法,频繁地进行垃圾收集。
  • 老年代:通常采用标记-整理或标记-清除算法,较少进行垃圾收集。

3. 虚拟机的退出

3.1 正常退出

  • 程序正常执行结束:当程序的所有非守护线程都终止时,JVM会自然退出。
  • 调用System.exit()方法 :任何线程都可以调用System.exit()方法来强制退出JVM。如果安全管理器允许,该方法会立即终止JVM。

3.2 异常退出

  • 程序在执行过程中遇到异常或错误而异常终止:例如,抛出未捕获的异常或出现严重的内部错误。
  • 由于操作系统错误而导致Java虚拟机进程终止:例如,操作系统崩溃或资源耗尽。

3.3 其他退出方式

  • 调用Runtime类的halt方法Runtime.halt()方法可以立即终止JVM,不执行任何清理工作。这通常用于紧急情况下的快速退出。
  • JNI Invocation API:通过JNI(Java Native Interface)规范描述的方法,可以使用JNI Invocation API来加载或卸载Java虚拟机。在这种情况下,JVM的退出由JNI调用控制。

3.4 关闭钩子

  • 定义:关闭钩子是一个已经初始化但尚未启动的线程,在JVM关闭时并发无序地执行。
  • 用途 :执行一些必要的清理工作,确保资源得到妥善释放。可以通过Runtime.addShutdownHook(Thread hook)方法注册关闭钩子。

4. 结论

JVM的生命周期涵盖了从启动到退出的全过程,其间涉及复杂的类加载、内存管理和垃圾收集机制。掌握这些知识有助于开发者编写更高效、更稳定的Java程序。同时,了解JVM内部的工作原理也能够帮助我们更好地进行性能调优和故障排查。


相关推荐
考虑考虑10 小时前
Jpa使用union all
java·spring boot·后端
用户37215742613511 小时前
Java 实现 Excel 与 TXT 文本高效互转
java
浮游本尊12 小时前
Java学习第22天 - 云原生与容器化
java
佛祖让我来巡山13 小时前
深入理解JVM内存分配机制:大对象处理、年龄判定与空间担保
jvm·内存分配·大对象处理·空间担保·年龄判定
渣哥14 小时前
原来 Java 里线程安全集合有这么多种
java
间彧14 小时前
Spring Boot集成Spring Security完整指南
java
间彧14 小时前
Spring Secutiy基本原理及工作流程
java
Java水解15 小时前
JAVA经典面试题附答案(持续更新版)
java·后端·面试
洛小豆17 小时前
在Java中,Integer.parseInt和Integer.valueOf有什么区别
java·后端·面试
前端小张同学18 小时前
服务器上如何搭建jenkins 服务CI/CD😎😎
java·后端