JVM启动过程中涉及哪些复杂环节和原理?

摘要:你可曾想过:当你在终端里敲下 java,在 main 方法真正运行之前,JVM 为了“创造一个可运行你的程序的宇宙”,到底经历了哪些步骤?从参数校验、系统资源探测,到选择垃圾回收器,再到类的加载、链接与初始化,这些看不见的过程决定了应用的启
你可曾想过:当你在终端里敲下 java,在 main 方法真正运行之前,JVM 为了“创造一个可运行你的程序的宇宙”,到底经历了哪些步骤?从参数校验、系统资源探测,到选择垃圾回收器,再到类的加载、链接与初始化,这些看不见的过程决定了应用的启动体验与后续性能。本文用一个极简的 HelloWorld 贯穿全程,结合详细日志,一步步洞察 JVM 的启动机制,帮你在调试和性能优化时更有抓手。 1. 概览 当我们运行一个 Java 应用时,JVM 在我们的代码真正开始执行之前,会先完成一系列复杂步骤。本文将从执行 java 命令的那一刻开始,一直走到应用就绪。 我们以一个简单的 HelloWorld 程序为例,拆解每一个阶段。理解这些内部机制能显著提升调试与性能调优的效果。 2. 从 java 命令到 JVM 启动 在 JVM 执行任何代码之前,它需要先启动、校验输入并配置运行环境。下面按启动顺序走一遍早期流程:从调用 java 命令到初始化 JVM 运行时。 2.1. java 命令与初始调用 当我们运行 java 命令时,JVM 启动序列会通过 JNI 方法 JNI_CreateJavaVM() 开始执行。该方法完成若干关键初始化任务,为执行 Java 应用准备环境。Java Native Interface(JNI)是 JVM 与原生系统库之间的桥梁,使 Java 与平台特性可以双向通信。 本文将使用详细日志观察 JVM 的内部运作,例如: java -Xlog:all=trace HelloWorldCopy 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 JVM 会验证目标可执行、类路径以及任何 JVM 参数,确保它们在继续执行前都是有效的。这个步骤能尽早捕获很多常见配置错误,避免后续阶段出现更难定位的问题。 2.3. 检测系统资源 接着,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. 这些信息会影响 JVM 的一些内部决策,比如默认选择哪个垃圾回收器。可用 CPU 数和总内存会直接影响 JVM 的启发式选择。不过,大多数设置都可以通过显式的 JVM 参数进行覆盖。在这个阶段,JVM 还会检查是否支持 Native Memory Tracking,并验证它可能依赖的各类操作系统工具的可用性。 2.4. 环境准备 随后,JVM 会生成 HotSpot 性能数据。
阅读全文