当前位置: 首页 > news >正文

通过 HelloWorld 深入剖析 JVM 启动过程

通过 HelloWorld 深入剖析 JVM 启动过程

在 Java 开发中,理解 JVM 的启动过程对于调试和性能优化至关重要。本文将通过一个简单的 HelloWorld 示例,深入探讨从运行 java 命令到应用程序启动的全过程,帮助开发人员更好地理解 JVM 的内部机制。

文章目录

  • 通过 HelloWorld 深入剖析 JVM 启动过程
    • 1. 概述
    • 2. 从 Java 命令到 JVM 启动
      • 2.1 Java 命令与初始调用
      • 2.2 参数验证
      • 2.3 系统资源检测
      • 2.4 环境准备
    • 3. 加载、链接和初始化
      • 3.1 垃圾回收器选择
      • 3.2 缓存数据存储加载
      • 3.3 创建方法区
      • 3.4 类加载
      • 3.5 类链接
      • 3.6 类初始化
    • 4. 优化 JVM 启动性能
      • 4.1 类加载的影响
      • 4.2 莱顿计划(Project Leyden)
      • 4.3 JVM 标志和调优
    • 5. 结论

1. 概述

运行 Java 应用程序时,JVM 会执行一系列复杂的初始化步骤,这些步骤为 Java 应用程序的运行奠定了基础。深入理解这些步骤可以显著提升我们在调试和性能调优方面的效率。

2. 从 Java 命令到 JVM 启动

2.1 Java 命令与初始调用

当我们运行 java 命令时,JVM 启动序列首先调用 JNI 方法 JNI_CreateJavaVM()。该方法负责执行必要的初始化任务,为 Java 应用程序的运行做好准备。JNI(Java Native Interface)作为 JVM 与本地系统库之间的桥梁,实现了 Java 代码与平台特定功能之间的无缝双向通信。

java -Xlog:all=trace HelloWorld

2.2 参数验证

JVM 会验证我们传递的参数,确保它们有效后才会继续执行。此验证步骤有助于在启动过程早期发现许多常见的配置错误,防止它们在后续阶段引发问题。

[0.006s][info][arguments] VM Arguments:
[arguments] jvm_args: -Xlog:all=trace:file=helloworld.log 
[arguments] java_command: HelloWorld
[arguments] java_class_path (initial): .
[arguments] Launcher Type: SUN_STANDARD

2.3 系统资源检测

接下来,JVM 会识别可用的系统资源,例如处理器数量、内存大小和关键系统服务。这些信息指导 JVM 做出一些内部决策,例如默认选择哪个垃圾回收器。

[0.007s][debug][os       ] Process is running in a job with 20 active processors.
[os       ] Initial active processor count set to 20
[os       ] Process is running in a job with 20 active processors.
[gc,heap  ]   Maximum heap size 4197875712
[gc,heap  ]   Initial heap size 262367232
[gc,heap  ]   Minimum heap size 6815736
[os       ] Host Windows OS automatically schedules threads across all processor groups.
[os       ] 20 logical processors found.

2.4 环境准备

然后,JVM 通过生成 HotSpot 性能数据来准备运行时环境。这些数据会被 JConsole 和 VisualVM 等性能分析工具使用。

[perf,datacreation] name = sun.rt._sync_Inflations, dtype = 11, variability = 2, units = 4, dsize = 8, vlen = 0, pad_length = 4, size = 56, on_c_heap = FALSE, address = 0x000001f3085f0020, data address = 0x000001f3085f0050

3. 加载、链接和初始化

3.1 垃圾回收器选择

JVM 内部的一个关键步骤是选择垃圾回收器。从 JDK 23 开始,默认情况下,JVM 选择 G1 GC,除非系统内存小于 1792MB 和/或系统是单处理器系统。

[gc               ] Using G1
[gc,heap,coops    ] Trying to allocate at address 0x0000000705c00000 heap of size 0xfa400000
[os               ] VirtualAlloc(0x0000000705c00000, 4198498304, 2000, 4) returned 0x0000000705c00000.
[os,map           ] Reserved [0x0000000705c00000 - 0x0000000800000000), (4198498304 bytes)
[gc,heap,coops    ] Heap address: 0x0000000705c00000, size: 4004 MB, Compressed Oops mode: Zero based, Oop shift amount: 3
[pagesize         ] Heap:  min=8M max=4004M base=0x0000000705c00000 size=4004M page_size=4K

3.2 缓存数据存储加载

JVM 开始寻求优化。CDS(Class Data Sharing)是一个已经过预处理的类文件归档,它可以显著提高 JVM 的启动性能。

[cds] trying to map [Java home]/lib/server/classes.jsa
[cds] Opened archive [Java home]/lib/server/classes.jsa

3.3 创建方法区

JVM 随后会创建方法区,这是一个特殊的堆外内存区域,用于存储类数据。HotSpot JVM 实现将此区域称为元空间。

[metaspace,map    ] Trying anywhere...
[metaspace,map    ] Mapped at 0x000001f32b000000

3.4 类加载

类加载是一个三步过程:找到类的二进制表示、从中派生出类,并将其加载到方法区。

public class HelloWorld extends Object {public static void main(String[] args) {System.out.println("Hello World!");}
}

3.5 类链接

类链接包含三个子过程——验证、准备和解析。这些步骤并非按顺序进行,解析可以在验证之前、类初始化之后的任何时间发生。

[class,init] Start class verification for: HelloWorld
[verification] Verifying class HelloWorld with new format
[verification] Verifying method HelloWorld.<init>()V

3.6 类初始化

类初始化会为静态字段赋值并执行静态初始化器。

4. 优化 JVM 启动性能

4.1 类加载的影响

为了测量 JVM 启动、加载类、链接类并执行我们简单程序所需的总时间,我们可以使用系统的时间实用程序。

time java HelloWorld

4.2 莱顿计划(Project Leyden)

莱顿计划旨在缩短启动时间、缩短达到峰值性能所需的时间并减少内存占用。JDK 24 引入了 JEP 483:提前类加载和链接,它会在启动前而不是启动时执行这些操作,从而显著提升启动性能。

4.3 JVM 标志和调优

虽然可以通过使用静态字段和初始化器来优化启动性能,但我们应该谨慎对待。大部分执行的代码来自依赖项,而不是我们自己的应用程序代码。因此,合理使用 JVM 标志(如 -XX:+UseG1GC-XX:MaxMetaspaceSize)可以进一步优化性能。

5. 结论

本文深入剖析了 JVM 在启动过程中经历的复杂流程,从验证用户输入、检测系统资源到加载、链接和初始化类。即使是简单的 HelloWorld 应用程序,JVM 也会在执行代码之前准备整个运行时环境,加载数百个类。随着 Project Leyden 的 AOT 功能等改进措施的推出,启动性能将持续提升。对于开发人员而言,理解这些机制不仅有助于调试和性能优化,还能帮助我们更好地设计和优化 Java 应用程序。

http://www.dtcms.com/a/596335.html

相关文章:

  • css-文字背景渐变色
  • Tailwind CSS的grid布局
  • LangGraph基础教程(4)---LangGraph的核心能力
  • 百度网站推广费用多少物流网站前端模板下载
  • Docker-镜像存储机制-网络
  • 线性代数 - 从方程组到行列式
  • 景德镇做网站公司中国邮政做特产的网站
  • 【Linux】进程间通信(三)System V 共享内存完全指南:原理、系统调用与 C++ 封装实现
  • 记一次cssd无法启动故障处理
  • 开源 Objective-C IOS 应用开发(一)macOS 的使用
  • ElasticSearch详解(篇一)
  • flash网站价格网站推广的特点
  • 【C++ 面试题】内存对齐
  • busybox:启动阶段的静态 IP 配置过程
  • k8s 中遇到Calico CrashLoopBackOff 的解决方法
  • zookeeper单机版安装
  • 【Excel导入】读取WPS格式嵌入单元格内的图片
  • 福清建设银行网站网红营销的作用
  • 34节点配电网牛顿-拉夫逊潮流计算 + 分布式电源(DG)多场景分析的 MATLAB
  • 分布式专题——53 ElasticSearch高可用集群架构实战
  • 电子商务网站建设与设计网站常州建设
  • 学习编程好么 | 编程的好处与学习路径分析
  • 从中间件的历史来看移动App开发的未来
  • Faster-Whisper:更快更好的开源Asr模型
  • ubuntu部署whisper+speaker_large+qwen【gradio界面版】
  • 阿里云通过中国信通院首批安全可信中间件评估
  • 正点原子【第四期】Linux之驱动开发学习笔记-12.1 Linux 阻塞和非阻塞 IO 实验
  • 做网站fjfzwl门户wordpress主题下载
  • Elasticsearch的用法
  • LLMChain for Chat Models in LangChain