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内部的工作原理也能够帮助我们更好地进行性能调优和故障排查。


相关推荐
Dr.Zhu3 分钟前
POI-TL插件开发-表格分组插件
java·windows·word·poi-tl
南宫生7 分钟前
力扣-图论-16【算法学习day.66】
java·学习·算法·leetcode·图论
Aileen_0v016 分钟前
【设计模式探索——智能遍历:如何用迭代器模式优化AI数据处理】
java·人工智能·设计模式·迭代器模式
真的爱学习嘛?22 分钟前
又要考试了
java·服务器·前端
一只大老铁24 分钟前
Ubuntu20.04解决docker安装后is the docker daemon running? 问题
java·docker·eureka
大大怪将军~~~~27 分钟前
了解 SpringMVC 请求流程
java·开发语言·spring
杞人何忧28 分钟前
关于redis锁的简单实现
java·redis
野蛮的大西瓜34 分钟前
大模型呼出机器人有哪些功能特点?
java·人工智能·语言模型·自然语言处理·机器人·信息与通信
只恨天高2 小时前
扩展SpringBoot中的SpringMVC的默认配置
java·spring boot·spring
CodeSheep程序羊3 小时前
吴恩达官宣开源,yyds!
java·javascript·人工智能·python·深度学习·神经网络·github