深入理解JVM

轩辕暗神 3月前 ⋅ 1125 阅读

准备环境

1操作系统,这里使用ubuntu20.4
2安装依赖环境,
2.1 安装基础环境
apt-get install -y wget unzip vim gcc g++  net-tools  telnet curl make openssl libssl-dev zlib1g zlib1g.dev  lrzsz --fix-missing
2.2 安装jvm依赖

下载openjdk12源码: https://hg.openjdk.org/jdk/jdk12/archive/tip.tar.gz 在Ubuntu系统上安装GCC的命令为:

apt-get install build-essential

OpenJDK编译依赖库:

工具库名称安装命令
FreeTypeThe FreeType Projectapt-get install libfreetype6-dev
CUPSCommon UNIX Printing Systemsudo apt-get install libcups2-dev
X11X Window Systemsudo apt-get install libx11-dev libxext-dev libxrender-dev libxrandr-dev libxtst-dev libxt-dev
ALSAAdvanced Linux Sound Architecturesudo apt-get install libasound2-dev
lbffiPortable Foreign Function Interface Librarysudo apt-get install libffi-dev
AutoconfExtensible Package of M4 Macrossudo apt-get install autoconf
数据单元格数据单元格数据单元格
##### 2.3 安装编译用的JDK
sudo apt-get install openjdk-11-jdk

需要下载的编译环境和依赖项目都齐备后,我们就可以按照默认配置来开始编译了,但通常我们编译OpenJDK的目的都不仅仅是为了得到在自己机器中诞生的编译成品,而是带着调试、定制化等需求,这样就必须了解OpenJDK提供的编译参数才行,这些参数可以使用“bash configure--help”命令查询到,笔者对它们中最有用的部分简要说明如下: · --with-debug-level=:设置编译的级别,可选值为release、fastdebug、slowde-bug,越往后进行的优化措施就越少,带的调试信息就越多。还有一些虚拟机调试参数必须在特定模式下才可以使 用。默认值为release。

· --enable-debug:等效于--with-debug-level=fastdebug。

· --with-native-debug-symbols=:确定调试符号信息的编译方式,可选值为none、internal、external、zipped。

· --with-version-string=:设置编译JDK的版本号,譬如java-version的输出就会显示该信息。这个参数还有--with-version-=的形式,其中part可以是pre、opt、build、major、minor、security、patch之一,用于设置版本号的某一个部分。

· --with-jvm-variants=[,...]:编译特定模式(Variants)的HotSpot虚拟机,可以多个模式并存,可选值为server、client、minimal、core、zero、custom。

· --with-jvm-features=[,...]:针对--with-jvm-variants=custom时的自定义虚拟机特性列表(Features),可以多个特性并存,由于可选值较多,请参见help命令输出。

· --with-target-bits=:指明要编译32位还是64位的Java虚拟机,在64位机器上也可以通过交叉编译生成32位的虚拟机。

· --with-=:用于指明依赖包的具体路径,通常使用在安装了多个不同版本的Bootstrap JDK和依赖包的情况。其中lib的可选值包括boot-jd、freetype、cups、x、alsa、libffi、jtreg、libjpeg、giflib、libpng、lcms、zlib。

· --with-extra-=:用于设定C、C++和Java代码编译时的额外编译器参数,其中flagtype可选值为cflags、cxxflags、ldflags,分别代表C、C++和Java代码的参数。

· --with-conf-name=:指定编译配置名称,OpenJDK支持使用不同的配置进行编译,默认会根据编译的操作系统、指令集架构、调试级别自动生成一个配置名称,譬如“linux-x86_64-server- release”,如果在这些信息都相同的情况下保存不同的编译参数配置,就需要使用这个参数来自定义配置名称。 以上是configure命令的部分参数,其他未介绍到的可以使用“bash configure--help”来查看,所有参数均通过以下形式使用:

bash configure [options]

譬如,编译FastDebug版、仅含Server模式的HotSpot虚拟机,命令应为:

bash configure --enable-debug --with-jvm-variants=server

configure命令承担了依赖项检查、参数配置和构建输出目录结构等多项职责,如果编译过程中需要的工具链或者依赖项有缺失,命令执行后将会得到明确的提示,并且给出该依赖的安装命令,这比编译旧版OpenJDK时的“make sanity”检查要友好得多,譬如以下例子所示:

configure: error: Could not find fontconfig! You might be able to fix this by running 'sudo apt-get install libfontconfig1-dev'. 
configure exiting with result code 1

解决办法:

# sudo apt-get install libfontconfig1-dev -y

如果一切顺利的话,就会收到配置成功的提示,并且输出调试级别,Java虚拟机的模式、特性, 使用的编译器版本等配置摘要信息,如下所示:

====================================================
A new configuration has been successfully created in
/opt/javaVm/jdk12-06222165c35f/build/linux-x86_64-server-fastdebug
using configure arguments '--enable-debug --with-jvm-variants=server'.

Configuration summary:
* Debug level:    fastdebug
* HS debug level: fastdebug
* JVM variants:   server
* JVM features:   server: 'aot cds cmsgc compiler1 compiler2 epsilongc g1gc graal jfr jni-check jvmci jvmti management nmt parallelgc serialgc services shenandoahgc vm-structs zgc' 
* OpenJDK target: OS: linux, CPU architecture: x86, address length: 64
* Version string: 12-internal+0-adhoc.root.jdk12-06222165c35f (12-internal)

Tools summary:
* Boot JDK:       openjdk version "11.0.21" 2023-10-17 OpenJDK Runtime Environment (build 11.0.21+9-post-Ubuntu-0ubuntu120.04) OpenJDK 64-Bit Server VM (build 11.0.21+9-post-Ubuntu-0ubuntu120.04, mixed mode, sharing)  (at /usr/lib/jvm/java-11-openjdk-amd64)
* Toolchain:      gcc (GNU Compiler Collection)
* C Compiler:     Version 9.4.0 (at /usr/bin/gcc)
* C++ Compiler:   Version 9.4.0 (at /usr/bin/g++)

Build performance summary:
* Cores to use:   1
* Memory limit:   1959 MB

在configure命令以及后面的make命令的执行过程中,会在“build/配置名称”目录下产生如下目录结构。不常使用C/C++的读者要特别注意,如果多次编译,或者目录结构成功产生后又再次修改了配 置,必须先使用“make clean”和“make dist-clean”命令清理目录,

make clean && make dist-clean

才能确保新的配置生效。编译产生的目录结构以及用途如下所示:

buildtools/:用于生成、存放编译过程中用到的工具hotspot/:HotSpot虚拟机编译的中间文件images/:使用make *-image产生的镜像存放在这里jdk/:编译后产生的JDK就放在这里
support/:存放编译时产生的中间文件
test-results/:存放编译后的自动化测试结果
configure-support/:这三个目录是存放执行configure、make和test的临时文件make-support/
test-support/

编译成功后执行make命令

make images 

全部评论: 0

    我有话说: