JVM(Java 虚拟机)
核心作用:执行 Java 字节码
JVM 是 Java 程序的运行时引擎,负责将编译后的 .class 字节码文件转换成计算机可执行的指令。它是实现 Java 跨平台(一次编译,到处运行)的核心。
JVM 核心功能:
- 字节码加载
- 通过 ClassLoader 加载 .class 文件到内存。
- 字节码验证
- 检查代码安全性(如防止非法内存访问)。
- 解释执行
- 解释器逐行将字节码翻译成机器码执行(启动快)。
- 即时编译(JIT)
- 将热点代码(频繁执行的代码)编译为本地机器码(执行快)。
- 内存管理
- 自动内存分配与垃圾回收(GC)。
- 管理内存区域:堆(对象存储)、栈(方法调用)、方法区(类信息)等。
- 平台适配
- 不同操作系统(Windows/Linux/macOS)有对应的 JVM 实现,屏蔽底层差异。
✅ 关键点:JVM 不直接执行 Java 源码,而是执行编译器生成的字节码。
JDK(Java Development Kit)
核心作用:Java 开发工具包
JDK 是开发 Java 应用的完整套件,包含:
-
开发工具
- javac:Java 编译器(将 .java 源码编译成 .class 字节码)。
- java:启动 JVM 执行程序。
- jar:打包工具。
- javadoc:文档生成工具。
- 调试器(如 jdb)。
-
基础类库(Java API)
- 如 java.lang(String、Object)、java.util(集合框架)、java.io(文件操作)等。
- JRE(Java Runtime Environment)
- 包含 JVM + 运行库(运行 Java 程序的最小环境)。
JDK 与 JVM 的关系:
- 开发阶段:使用 JDK 中的 javac 编译代码。
- 运行阶段:使用 JDK 中的 java 命令启动 JVM 执行程序。
工作流程示例
graph LR
源码[编写 Hello.java] --> 编译[JDK的javac编译]
编译 --> 字节码[生成 Hello.class]
字节码 --> 执行[JDK的java命令启动JVM]
执行 --> 机器码[JVM解释/JIT编译]
机器码 --> CPU[CPU执行]
核心区别总结
组件 | 角色 | 关键内容 | 是否包含 JVM |
JDK | 开发工具包 | 编译器、调试器、类库、JRE | ✅ 包含 |
JVM | 字节码执行引擎 | 解释器、JIT、GC、内存管理 | ❌ 自身即核心 |
通俗比喻
- JDK 像汽车维修厂
- 提供所有工具(扳手、千斤顶 = javac/jar)和零件(类库)。
- JVM 像发动机
- 负责将燃料(字节码)转化为动力(机器码),驱动汽车(程序)运行。
- JRE 像一辆完整汽车
- 包含发动机(JVM)+ 基础零件(运行库),能开但不含维修工具。
💡 开发者需要 JDK(含 JVM),用户只需 JRE(含 JVM)即可运行程序。现代 JDK 已内置 JRE。
字节码如何被计算机执行
生成的 .class 文件不直接被 CPU 执行,而是由 JVM 解释或编译为机器码:
- 解释器:逐行翻译字节码执行(启动快)。
- JIT 编译器:将热点代码编译为本地机器码(执行快)。
- 最终执行:转换后的机器码由 CPU 直接运行。
安装 JDK 后为什么配置环境变量?
1、核心原因:解决路径识别问题
操作系统不知道 JDK 安装在哪里,需要显式指定路径才能找到关键工具:
- 命令行工具:如 javac(编译)、java(运行)、jar(打包)
- 开发工具:如 IDE(IntelliJ IDEA/Eclipse)、构建工具(Maven/Gradle)
若不配置环境变量,每次执行命令都需输入完整路径(例如:C:\Program Files\Java\jdk-17\bin\javac Hello.java),极其繁琐。
2、需要配置的关键环境变量
1. JAVA_HOME(最重要)
- 作用:指向 JDK 的安装根目录(例如:C:\Program Files\Java\jdk-17)
- 为什么需要:
- 开发工具依赖:Maven/Gradle/Tomcat 等工具通过 JAVA_HOME 自动定位 JDK
- 路径简化:其他路径可基于此变量扩展(如 %JAVA_HOME%\bin)
2. PATH
- 作用:添加 JDK 的 bin 目录(例如:%JAVA_HOME%\bin)
- 为什么需要:
- 允许在任意目录下直接运行 javac、java 等命令
- 无需输入完整路径:终端直接识别 javac Hello.java
3、不配置环境变量的后果
场景 | 问题现象 |
命令行编译运行 | 报错 'javac' 不是内部或外部命令(Windows)或 command not found(Linux/macOS) |
启动 IDE(如 IDEA) | 需手动指定 JDK 路径,否则无法编译运行 |
使用 Maven/Gradle | 构建失败,提示找不到 JDK |
运行 Tomcat 等服务器 | 启动报错,提示 JAVA_HOME is not set correctly |
4、IDE 需要环境变量吗?
- 不强制但推荐:
IDEA/Eclipse 可手动指定 JDK 路径(不依赖环境变量),但:- 构建工具仍依赖:Maven/Gradle 构建时仍需 JAVA_HOME
- 终端集成失效:IDE 内置终端无法识别 javac 等命令
- 外部工具兼容性:如 Docker/CI 工具链依赖全局环境变量
5、总结:为什么必须配置?
需求 | 环境变量作用 |
全局调用 JDK 命令 | PATH 添加 bin 目录 |
开发工具自动发现 JDK | JAVA_HOME 提供根路径 |
跨平台一致性 | 所有系统通过相同变量名访问 JDK |
避免重复路径输入 | 命令行直接执行 java/javac |
✅ 本质:环境变量是操作系统级别的路径注册机制,让 JDK 从“一个普通安装目录”变成“系统可识别的开发环境”。