一、前言
对于java来说,很多工作都被jvm包揽了,比方内存调配和回收、其余零碎级别调用。这其实就把操作系统底层的一些货色给屏蔽了,对于javaer来说,不便的同时也带来一些困惑(我还不是一个纯javaer),很多细节性概念始终不是很通透,特地是当波及底层交互的时候。特地是学NIO那块货色的时候(epoll&poll?、zero-copy?、userbuffer?、kernel buffer?
)。
为了解决心田的种种纳闷,还是筹备学习jdk的底层源码。首先须要下载jdk源码,并在本地编译,上面开整(还是有很多坑):
二、本地环境
- macOS Monterey 12.0.1;
- 须要装置XCode【下载地址】,本地装置版本13.1;
- brew install freetype & brew install ccache
三、JDK9的坑
- 首先下载JDK9源码,下载地址:https://github.com/campolake/...;
在源码根目录执行如下命令(环境检查和配置):
bash ./configure --with-debug-level=slowdebug --with-jvm-variants=server --enable-ccache --with-freetype=/usr/local/Cellar/freetype/2.11.0 --disable-warnings-as-errors
freetype
(字体引擎)门路依据本地环境本人更改;ccache
缓存编译代码,减速编译,能够不必;disable-warnings-as-errors
防止将warning信息当成error;with-debug-level
用来设置编译的级别,可选值为release、fastdebug、slowde-bug,越往后进行的优化措施就越少,带的调试信息就越多。
执行完呈现如下提醒就示意能够下一步了:
A new configuration has been successfully created in /Users/***/CLionProjects/openjdk9/build/macosx-x86_64-normal-server-slowdebug using configure arguments '--with-debug-level=slowdebug --with-jvm-variants=server --enable-ccache --with-freetype=/usr/local/Cellar/freetype/2.11.0 --disable-warnings-as-errors'. Configuration summary: * Debug level: slowdebug * HS debug level: debug * JDK variant: normal * JVM variants: server * OpenJDK target: OS: macosx, CPU architecture: x86, address length: 64 * Version string: 9-internal+0-2021-12-03-105259.***.openjdk9 (9-internal) Tools summary: * Boot JDK: java version "1.8.0_281" Java(TM) SE Runtime Environment (build 1.8.0_281-b09) Java HotSpot(TM) 64-Bit Server VM (build 25.281-b09, mixed mode) (at /Library/Java/JavaVirtualMachines/jdk1.8.0_281.jdk/Contents/Home) * Toolchain: clang (clang/LLVM from Xcode 13.1) * C Compiler: Version 13.0.0 (at /usr/bin/clang) * C++ Compiler: Version 13.0.0 (at /usr/bin/clang++) Build performance summary: * Cores to use: 16 * Memory limit: 32768 MB * ccache status: Active (4.5.1) The following warnings were produced. Repeated here for convenience: WARNING: Ignoring value of CCACHE from the environment. Use command line variables instead.
执行
make images
,开始编译;
事件当然没有那么简略,在这一步胜利呈现了报错,如下:/Users/yulewei/jdk9/hotspot/src/share/vm/memory/virtualspace.cpp:585:14: error: ordered comparison between pointer and zero ('char *' and 'int')if (base() > 0) { ~~~~~~ ^ ~.../Users/yulewei/jdk9/hotspot/src/share/vm/opto/lcm.cpp:42:35: error: ordered comparison between pointer and zero ('address' (aka 'unsigned char *') and 'int')if (Universe::narrow_oop_base() > 0) { // Implies UseCompressedOops. ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~ .../Users/yulewei/jdk9/hotspot/src/share/vm/opto/loopPredicate.cpp:915:73: error: ordered comparison between pointer and zero ('const TypeInt *' and 'int') assert(rng->Opcode() == Op_LoadRange || _igvn.type(rng)->is_int() >= 0, "must be"); ~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~
这个是JDK9的bug,须要批改源码文件而后从新编译,参考这篇文章解决:https://segmentfault.com/a/11...
改完源码文件从新编译,呈现新的报错:
* For target hotspot_variant-server_libjvm_gtest_objs_gtestMain.o:clang: warning: include path for libstdc++ headers not found; pass '-stdlib=libc++' on the command line to use the libc++ standard library instead [-Wstdlibcxx-not-found]In file included from /Users/***/CLionProjects/openjdk9/hotspot/test/native/gtestMain.cpp :33:In file included from /Users/***/CLionProjects/openjdk9/hotspot/test/native/unittest.hpp: 29:/Users/***/CLionProjects/openjdk9/test/fmw/gtest/include/gtest/gtest.h:54:10: fatal error: 'limits' file not found#include <limits> ^~~~~1 error generated.* For target hotspot_variant-server_libjvm_gtest_objs_test_os.o:clang: warning: include path for libstdc++ headers not found; pass '-stdlib=libc++' on the command line to use the libc++ standard library instead [-Wstdlibcxx-not-found]In file included from /Users/***/CLionProjects/openjdk9/hotspot/test/native/runtime/test_os.cpp:25:In file included from /Users/***/CLionProjects/openjdk9/hotspot/src/share/vm/runtime/os.hpp:29:In file included from /Users/***/CLionProjects/openjdk9/hotspot/src/share/vm/runtime/extendedPC.hpp:28:/Users/***/CLionProjects/openjdk9/hotspot/src/share/vm/memory/allocation.hpp:38:10: fatal error: 'new' file not found#include <new> ^~~~~
这个问题是因为XCode版本比拟新导致,找不到C语言相干的头文件。其实XCode中是有的,只是门路和老的不一样了,在
configure
命令中增加如下3个参数就行:--with-extra-cflags=-stdlib=libc++ --with-extra-cxxflags=-stdlib=libc++ --with-extra-ldflags=-stdlib=libc++
。
configure命令就是这样的了:bash ./configure --with-debug-level=slowdebug --with-jvm-variants=server --enable-ccache --with-freetype=/usr/local/Cellar/freetype/2.11.0 --disable-warnings-as-errors --with-extra-cflags=-stdlib=libc++ --with-extra-cxxflags=-stdlib=libc++ --with-extra-ldflags=-stdlib=libc++
再一次执行
make images
呈现如下报错:## A fatal error has been detected by the Java Runtime Environment:## SIGILL (0x4) at pc=0x0000000106321898, pid=39315, tid=8195## JRE version: OpenJDK Runtime Environment (9.0) (slowdebug build 9-internal+0-2021-12-03-133118.chensheng.openjdk9)# Java VM: OpenJDK 64-Bit Server VM (slowdebug 9-internal+0-2021-12-03-133118.chensheng.openjdk9, mixed mode, tiered, compressed oops, serial gc, bsd-amd64)# Problematic frame:# V [libjvm.dylib+0xc1e898] PerfData::~PerfData()+0x8## No core dump will be written. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again## If you would like to submit a bug report, please visit:# http://bugreport.java.com/bugreport/crash.jsp#
google了一圈,有的说是硬件问题,最初切实没搞定,就换成JDK11了。
四、编译JDK11
- 首先须要先在本地装置jdk11(jdk11能够用来编译jdk11,不须要低一个版本的jdk),能够间接下载压缩包而后解压(不须要配置环境变量)
- 下载JDK11源码:https://github.com/openjdk/jd...
执行
configure
bash ./configure --with-debug-level=slowdebug --with-boot-jdk=/Users/***/Applications/jdk11/jdk-11.0.12.jdk/Contents/Home --with-jvm-variants=server --enable-ccache --disable-warnings-as-errors --with-extra-cflags=-stdlib=libc++ --with-extra-cxxflags=-stdlib=libc++ --with-extra-ldflags=-stdlib=libc++
--with-boot-jdk
参数的值就是咱们解压后jdk11的绝对路径执行
make images
,一次胜利。阐明了一个问题,新版本(
os
&XCode
)和新版本(jdk
)才更适配
五、应用clion调试hotspot虚拟机
clion默认是用cmake
,然而编译openjdk是用make
,如果不想本人写cMakeList
且想缩小出问题概率,参考这篇文章:https://segmentfault.com/a/11...。
不出意外,肯定能够一步到位。
环境终于搞定了,又要开始学C语言了? {{{(>_<)}}}。