最近在看synchronized 锁优化方面的内容,有些地方看起来不是很方便,干脆就编译个源码来看看。

在windows上编译

由于自己常用的电脑操作系统是win10,所以最开始是想要在win10上编译的,但是一来网上文章太少,二来在windows上编译确实麻烦太多了(windows可以参考深入理解JVM虚拟机这本书),故放弃了。

MAC环境

准备

获取源码

OpenJDK源码使用Mercurial管理,如果通过版本库下载,则需要安装Mercurial,我们借助homebrew包管理器来安装

brew install mercurial

如果你的电脑没有安装homebrew,那么可以使用下面的命令来安装

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

安装完成后使用以下命令clone源代码

cd ~/jvm
hg clone https://hg.openjdk.java.net/jdk/jdk12

命令运行之后,openjdk的源码并没有下载下来

由于我并没有使用hg的方式,关于这部分可以参考闪电侠的文章https://www.jianshu.com/p/ee7e9176632c

当然我非常不建议你使用Mercurial的方式下载,这种方式不久要等很久,而且还需要科学上网才稳妥。我墙裂推荐你直接通过页面下载OpenJdk12源码压缩包)

比如我下载的是gz格式的文件(选择什么格式并不重要)。

如果你使用的Chrome,那么可以开启多线程下载,速度会有一个很明显的提升。

Bootstrap JDK

因为OpenJDK的各个组成部分有的是使用C++编写的,有的是使用Java编写的,因此编译这些Java代码需要使用到一个可用的JDK,官方称这个JDK为“Bootstrap JDK",一般来说只需要比编译的JDK第一个版本,这里采用OpenJDK11,可以通过这个网址 https://jdk.java.net/archive/ 下载
记住一定要下载一个适合Mac平台的OpenJDK11。

我使用的Bootstrap JDK版本如下

openjdk version "11.0.2" 2019-01-15
OpenJDK Runtime Environment 18.9 (build 11.0.2+9)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.2+9, mixed mode)

安装依赖

# 用于生成shell脚本的工具,可以使软件包在不同的系统下都可以编译
brew install autoconf# 字体引擎
brew install freetype

XCode 和 Command Line Tools for Xcode

这两个SDK提供了OpenJDK所需的编译器以及Makefile中用到的外部命令。一般电脑上都自带安装了。

网上很多编译出错都是因为XCode版本问题,导致报错,我也遇到了这个坑。

configure: error: No xcodebuild tool and no system framework headers found, use --with-sysroot or --with-sdk-name to provide a path to a valid SDK/Users/.../.../xxx.sh: line 82: 5: Bad file descriptorconfigure exiting with result code 1

最终我通过官网下载https://developer.apple.com/download/more/安装了9.4.1版本的XCode才搞定了。

下载xcode需要登录,如果没有账号可以申请一个

我选择的是手动下载xcode安装的方式,你可以先只下载Command Line Tools (macOS 10.13) for Xcode 9.4.1 安装看能不能解决你的问题,如果不能再下载Xcode(这个很大,大概4个多G)

编译jdk

源码下载好之后,我解压放到了这个/Users/naver/jvm/jdk12-06222165c35f目录下,下面的命令均是在这个目录下执行的。

bash configure  --with-boot-jdk='/usr/local/jdk-11.0.2.jdk/Contents/Home' --with-debug-level=slowdebug --with-target-bits=64 --disable-warnings-as-errors --enable-dtrace --with-jvm-variants=server

--with-boot-jdk:指定Bootstrap JDK路径
--with-debug-level:编译级别,可选值为release、fastdebug、slowdebug和optimized,默认值为release,如果我们要调试的话,需要设定为fastdebug或者slowdebug,建议设置为slowdebug
--with-target-bits:指定编译32位还是64位的虚拟机
--disable-warnings-as-errors:避免因为警告而导致编译过程中断
--enable-dtrace:开启一个性能工具
--with-jvm-variants:编译特定模式下的虚拟机,一般这里编译server模式
--with-conf-name:指定编译配置的名称,如果没有指定,则会生成默认的配置名称macosx-x86_64-server-slowdebug,我这里采用默认生成配置

在很多场景下编译OpenJDK都会使用--enable-ccache参数,来通过ccache加快编译速度,但我没有采用,因为目前编译速度其实不慢,再有就是如果增加了这个参数,后续导入到CLion的时候,会出现很多红字提示,看着好像不影响使用,但总归看着不太舒服

生成Compilation Database

在配置CLion的时候,直接import编译好之后的jdk源码,你会发现头文件都是红色的,无法找到提示,是因为CLion生产的CMakeLists.txt有问题,如果想要解决这个问题就需要修改这个文件,很明显我不会修。

最后通过JetBrains说的利用Compilation Database (https://blog.jetbrains.com/clion/2020/03/openjdk-with-clion/) 在CLion中构建OpenJDK解决了这个问题。

make CONF=macosx-x86_64-server-slowdebug compile-commands

执行完该命令,就会在${source_root}/build/macosx-x86_64-server-slowdebug下生成compile_commands.json文件。

编译

在导入CLion之前,要编译一下,因为某些模块使用了预编译头,如果不编译,CLion会在索引过程中提示找不到各种各样的文件。

make CONF=macosx-x86_64-server-slowdebug

测试

至此,证明我们已经编译完成了JDK12

CLion调试

导入project

在导入project之前先配置好Toolchains(Preferences进入)

配置好Toolchains后,通过File -> Open功能,选中${source_root}/build/macosx-x86_64-server-slowdebug/compile_commands.json,As a project打开,这样就导入了Compilation Database文件,接下来CLion开始进行索引。

这时候,你会发现你是看不到源码的,所以下面需要修改项目的根目录,通过Tools -> Compilation Database -> Change Project Root功能,选中你的源码目录,也就是${source_root},这样设置就可以在CLion中看到源代码啦。

${source_root}指的是 /Users/naver/jvm/jdk12-06222165c35f

debug之前配置

需要在Preferences --> Build, Exceution, Deployment --> Custom Build Targets配置构建目标

由于我这里已经配置好了,所以这里显示的是编辑页面,第一次配置要点击+,进行新增即可。

通过这两个配置每次构建之前都会重新编译我们的jdk,修改jvm代码之后可以直接进行重新调试。

debug 配置

Executable:选择${source_root}/build/macosx-x86_64-server-slowdebug/jdk/bin/java,或者其它你想调试的文件,比如javac;
Before luanch:这个下面新增的时候有一个bug,去掉就不会每次执行都去Build,节省时间,但其实OpenJDK增量编译的方式,每次Build都很快,所以就看个人选择了。

debug

${source_root}/src/java.base/share/native/libjli/java.c的401行打断点,点击Debug,然后F9放掉,不出意外你会遇到下面这个问题

由于我们使用的LLDB进行debug的,所以在进入第一个断点的时候在LLDB下执行以下命令可以避免此类问题

pro hand -p true -s false SIGSEGV SIGBUS

最终就可以看到java -version的输出效果如下

不过每次debug的时候都要输入这么一句就很麻烦,所以我们可以在**~/.lldbinit**文件中,使用如下命令,实现每次Debug时自动打个断点,然后输入pro hand -p true -s false SIGSEGV SIGBUS,最后继续执行后续流程,文件内容如下(其中main.c文件的路径自行替换)

breakpoint set --file /Users/naver/jvm/jdk12-06222165c35f/src/java.base/share/native/launcher/main.c --line 98 -C "pro hand -p true -s false SIGSEGV SIGBUS" --auto-continue true

与Java程序联合debug

上面演示的实际是java -version如何debug,那么如何做到通过自己编写的java代码作为程序入口来调试呢?

首先java代码如下(我用idea编写的):

CLion中配置如下

运行结果如下:

参考文档

<<深入理解Java虚拟机:JVM高级特性与最佳实践>>

mac下编译openjdk1.9及集成clion动态调试

在MacOS系统上使用CLion编译并调试OpenJDK

关注我不迷路

你的关注是对我最大的鼓励,是兄弟就关注我(狗头保命)

费尽九牛二虎之力,终于我成功编译并调试了JVM相关推荐

  1. 小白费了九牛二虎之力终于安装上了anaconda!

    小白费了九牛二虎之力终于安装上了anaconda! 1.下载 从官网https://www.anaconda.com/download/上下载适合自己电脑的anaconda 2.安装 双击下载好的an ...

  2. linux上热编译react,reactos终于被成功编译通过

    总结如下: 1.reactos是一款全面兼容winapi接口的供学习研究目的的操作系统,属于自由软件,同时也是开源的(www.reactos.org).另外,reactos与wine项目是属于同一拨人 ...

  3. reactos终于被成功编译通过

    总结如下: 1.reactos是一款全面兼容winapi接口的供学习研究目的的操作系统,属于自由软件,同时也是开源的(www.reactos.org).另外,reactos与wine项目是属于同一拨人 ...

  4. 耗时半月滴滴3面,费尽九牛二虎之力才拿offer,入职三天现已失业!

    从6月份开始,打算找工作,一个偶然的机会,拉勾上一个滴滴的师兄找到我,说要内推,在此感谢姚师兄,然后就开始了滴滴的面试之旅.把简历发过去之后,就收到了邮件通知,10个工作日联系我,请耐心等待. 没过2 ...

  5. 费了九牛二虎之力搞定女儿的户口

    费了九牛二虎之力,终于办好了女儿的户口,终于落户广州市,下一步是将户口从广州调到深圳,之前办理女儿户口的时候将相关的资料都顺便给办了,后面应该比较顺利了. 这几年一直在外飘,我和老婆的户口在天南地北, ...

  6. 看完这篇文章之后,终于明白了编译到底怎么回事。

    看完这篇文章之后,终于明白了编译到底怎么回事. 1 对于同一个语句,有如下三种:高级语言.低级语言.机器语言的表示 C语言  a=b+1; 汇编语言  mov -0xc(%ebp),%eax add ...

  7. 看完这篇文章之后,终于明白了编译到底怎么回事

    看完这篇文章之后,终于明白了编译到底怎么回事. 1 对于同一个语句,有如下三种:高级语言.低级语言.机器语言的表示 C语言  a=b+1; 汇编语言  mov -0xc(%ebp),%eax add ...

  8. FFmpeg4.1编译:mac+android-ndk-14b+ffmpeg4.1成功编译

    一,下载FFmpeg4.1 使用源码: git clone git://source.ffmpeg.org/ffmpeg.git ffmpeg 下载到你向的目录下,我是新建了一个文件夹buildffm ...

  9. [Android 编译(一)] Ubuntu 16.04 LTS 成功编译 Android 6.0 源码教程

    1 前言 经过3天奋战,终于在Ubuntu 16.04上把Android 6.0的源码编译出来了,各种配置,各种error,各种爬坑,特写此博客记录爬坑经历.先上图,Ubuntu上编译完后成功运行模拟 ...

最新文章

  1. 预计2024年全球医疗AI市场超100亿美元
  2. 百度面试 中缀表达式变成后缀表达式
  3. jsp页面间的传值方法
  4. google套件_Google 推出 3 款语音识别应用,想用 AI 帮语言障碍者说话
  5. qq浏览器主页_安卓浏览器哪家强?这些小众好用的手机浏览器你知道吗
  6. 微软正式推出 gRPC-Web for .NET
  7. Thread多线程一起执行睡眠,同时分开执行,实例
  8. Windows Media Services 9 系列常见问题解答
  9. c语言输入m行m列的二维数组,编写一个函数,用于计算具有n行和m列的二维数组中指定列的平均值以及数组各行的和的最小值。...
  10. SCM供应链协同管理系统解决方案
  11. Boost电路硬件设计实例
  12. 关于指针赋初值为NULL的问题
  13. Aspose.word基础
  14. linux下eeprom读写测试,本科毕业设计__基于linux的eeprom的读写控制.doc
  15. 接口自动化测试之接口测试基础
  16. scala中的sealed
  17. 似然函数和最大似然估计
  18. ipad全系列_为iPad提供全职工作
  19. DIP分组器核心c#源代码优化封版,三个城市DIP数据分析
  20. plantuml 依赖_PlantUML参考手册

热门文章

  1. Ubuntu下无法切换root用户,su: Authentication failure
  2. 个人面试记录 - 抖音音乐11.13~11.30
  3. python自带rbf函数吗_径向基函数(RBF)神经网络
  4. 因为不懂Maven,被开了!
  5. RESTful 最佳实践
  6. 小儿计算机编程是什么意思,小儿趣味编程是什么,幼儿学习编程的好处以及要点...
  7. 音视频技术开发周刊(第119期)
  8. java 数据格式校验_Java对json是否合法进行格式校验详解
  9. selenium+python自动化77-autoit文件上传【转载】
  10. 粗糙集 matlab,粗糙集理论权重确定方法用matlab实现