JDK17编译指南:从源码到定制化JVM

📅 2026/8/9 6:39:44
JDK17编译指南:从源码到定制化JVM
1. 为什么需要自己编译JDK17在开始动手之前我们先聊聊为什么要自己编译JDK。很多人可能会问直接从官网下载编译好的二进制包不香吗确实对于大多数开发者来说直接使用预编译的JDK是最方便的选择。但如果你遇到以下场景自己编译JDK就变得很有必要了你需要为特定硬件平台如ARM架构定制JDK你想修改或扩展JDK的某些功能比如添加新的JVM参数你需要调试JDK内部的实现细节比如研究HotSpot虚拟机的工作原理你想为JDK贡献代码OpenJDK是开源的欢迎社区贡献我最近就因为需要研究JVM的GC日志实现细节不得不自己编译JDK。在这个过程中踩了不少坑也积累了一些经验下面就把完整的编译过程分享给大家。2. 编译环境准备2.1 硬件要求编译JDK是个资源密集型任务建议准备至少16GB内存32GB更佳至少100GB可用磁盘空间SSD最佳多核CPU8核以上能显著缩短编译时间提示如果机器配置不够可以尝试减少并行编译线程数但编译时间会大幅增加。2.2 操作系统选择官方支持的平台包括Linux推荐Ubuntu 20.04 LTSmacOS10.13及以上Windows需要WSL2或Cygwin我个人推荐使用Linux系统因为依赖管理更方便编译环境更接近生产环境问题排查资料更丰富2.3 软件依赖安装以Ubuntu 20.04为例需要安装以下依赖sudo apt update sudo apt install -y git build-essential libx11-dev libxext-dev libxrender-dev \ libxtst-dev libxt-dev libcups2-dev libfontconfig1-dev libasound2-dev \ libfreetype6-dev autoconf zip unzip如果是其他系统可以参考OpenJDK官方文档中的 构建要求 。3. 获取JDK17源码3.1 克隆OpenJDK仓库JDK17的源码托管在GitHub上git clone https://github.com/openjdk/jdk17u.git cd jdk17u如果网络连接不稳定可以考虑使用国内镜像git clone https://gitee.com/mirrors/openjdk-jdk17u.git3.2 选择正确的分支JDK17有多个更新版本建议选择最新的稳定分支git checkout jdk-17.0.610 # 以最新发布的更新版本为准可以通过git tag -l查看所有可用版本。4. 配置编译环境4.1 设置Bootstrap JDK编译JDK17需要一个已有的JDK作为引导Bootstrap JDK要求版本为JDK16或JDK17sudo apt install openjdk-17-jdk export JAVA_HOME/usr/lib/jvm/java-17-openjdk-amd64验证Bootstrap JDK$JAVA_HOME/bin/java -version应该输出类似以下内容openjdk version 17.0.6 2023-01-17 OpenJDK Runtime Environment (build 17.0.610) OpenJDK 64-Bit Server VM (build 17.0.610, mixed mode)4.2 运行配置脚本JDK使用Autoconf系统进行配置bash configure --enable-debug --with-jvm-variantsserver常用参数说明--enable-debug生成带调试信息的版本--with-jvm-variantsserver编译server版JVM默认--disable-warnings-as-errors将警告视为非致命错误如果配置成功会输出类似以下信息Configuration summary: * Debug level: fastdebug * HS debug level: fastdebug * JVM variants: server * OpenJDK target: OS: linux, CPU architecture: x86, address length: 645. 开始编译5.1 执行编译命令使用make命令开始编译make images这个命令会编译出完整的JDK镜像包括完整的JDK在build/linux-x86_64-server-fastdebug/images/jdk精简的JRE在build/linux-x86_64-server-fastdebug/images/jre5.2 控制编译过程查看编译进度make LOGinfo images并行编译加快速度make JOBS4 images根据CPU核心数调整只编译HotSpot VMmake hotspot只编译javac编译器make java.compiler编译过程可能需要30分钟到数小时取决于机器性能。6. 验证编译结果6.1 检查编译产物编译完成后可以验证生成的JDK./build/linux-x86_64-server-fastdebug/images/jdk/bin/java -version应该输出类似openjdk version 17-internal 2021-09-14 OpenJDK Runtime Environment (fastdebug build 17-internal0-adhoc.user.jdk17u) OpenJDK 64-Bit Server VM (fastdebug build 17-internal0-adhoc.user.jdk17u, mixed mode)注意这里的版本号包含internal和fastdebug表示这是我们自己编译的调试版本。6.2 运行测试用例为了确保编译的JDK功能正常可以运行一些基本测试make test-tier1这个命令会运行一组基本的JVM和核心库测试。7. 常见问题与解决方案7.1 编译失败缺少依赖错误示例checking for freetype... configure: error: Could not find freetype!解决方案sudo apt install libfreetype6-dev7.2 内存不足错误示例g: fatal error: Killed signal terminated program cc1plus解决方案增加swap空间减少并行编译线程make JOBS2 images7.3 版本不匹配错误示例error: The supplied boot JDK (version 16) is not a valid JDK 17 image.解决方案确保使用JDK17作为Bootstrap JDK。8. 高级技巧8.1 增量编译修改源码后可以只重新编译变更部分make hotspot8.2 生成IDE项目文件生成Eclipse项目文件make eclipse-project生成IntelliJ IDEA项目文件make ide-project8.3 调试JVM编译debug版本后可以使用gdb调试JVMgdb --args ./build/linux-x86_64-server-fastdebug/images/jdk/bin/java -version9. 实际应用场景9.1 修改JVM参数假设我们想添加一个自定义的JVM参数修改src/hotspot/share/runtime/globals.hpp添加experimental(intx, MyCustomParam, 100, \ A custom parameter for testing) \重新编译HotSpotmake hotspot使用新参数./build/linux-x86_64-server-fastdebug/images/jdk/bin/java -XX:UnlockExperimentalVMOptions -XX:MyCustomParam2009.2 添加新的JNI方法如果想在JDK中添加新的native方法在Java类中声明native方法生成头文件javac -h ...在对应native文件中实现方法重新编译对应模块10. 性能优化建议10.1 使用ccache加速编译安装ccachesudo apt install ccache配置环境变量export CCccache gcc export CXXccache g10.2 选择性编译如果只研究特定模块可以只编译相关部分只编译核心库make java.base只编译NIO模块make java.nio10.3 使用tmpfs将编译目录挂载到内存文件系统sudo mount -t tmpfs -o size20G tmpfs /path/to/build/dir这能显著提高编译速度但需要足够的内存。11. 后续学习建议成功编译JDK只是开始如果想深入理解JDK实现从java.base模块开始阅读源码重点关注HotSpot虚拟机实现核心类库如java.lang, java.utilJNI机制使用调试器单步跟踪关键流程如类加载、方法调用参与OpenJDK社区讨论和贡献我自己在阅读JDK源码时发现从JVM启动流程main.c的JLI_Launch方法开始跟踪是个不错的切入点。