深入理解Java虚拟机[笔记]

1 走进Java

1.1 Java虚拟机家族

一、虚拟机始祖:Sun Classic/Exact VM

(1)Classic VM:只能使用纯解释器的方式执行Java代码,如果要使用即时编译器就必须进行外挂。

(2)Exact VM:使用准确式内存管理(有能力分辨哪些内存是引用类型,这也是在垃圾收集时判断堆上的数据是否还可能被使用的前提)。

二、武林盟主:HotSpot VM

  • 准确式内存管理
  • 热点代码探测:可以通过执行计数器找到最具编译佳值的代码,然后通知即时编译器以方法为单位进行编译。

三、天下第二:J9 VM

模块化做得好

1.2 新一代即时编译器

一、HotSpot VM中的两个即时编译器

编译速度 代码优化质量
客户端编译器
服务端编译器

二、服务公开与微服务区别

某服务增加功能时
服务公开 缩小进程范围
微服务 只在某种特定服务中增加所需功能,不影响整体进程架构

三、提前编译

提前编译是相对于即时编译的概念。

(1)优点

  • 减少即时编译带来的预热时间,减少Java应用长期给人带来的“第一次运行慢”的不良体验

(2)缺点

  • 必须为每个不同的硬件、操作系统编译对应的发行包
  • 显著降低Java链接过程的动态性

四、满足提前编译的Substrate VM

(1)优点

  • 可以直接从目标程序开始运行,而无需重复进行Java虚拟机的初始化过程
  • 显著降低内存占用及启动时间

(2)缺点

  • 要求目标程序是完全封闭的,也就是不能动态加载其他编译期不可知的代码和类库

1.3 发展的HotSpot

HotSpot现在支持

(1)模块化

(2)开放大量的编程接口

1.4 OpenJDK与OracleJDK的关系

image-20211224103519227

除去OpenJDK支持的字体渲染和OracleJDK支持的JFR,两者代码实质上几乎一致。

1.5 实战:自己编译JDK

一、源码获取

(1)https://hg.openjdk.java.net/jdk/jdk12

(2)点击左边菜单的browse

(3)点击zip即刻开始下载

image-20211224104023792

二、系统环境

Ubuntu18.04

三、构建编译环境

(1)安装GCC

1
sudo apt install build-essential

(2)安装OpenJDK编译依赖库

1
2
3
4
5
6
sudo apt install libfreetype6-dev
sudo apt install libcups2-dev
sudo apt install libx11-dev libxext-dev librender-dev libxrandr-dev libxtst-dev libxt-dev
sudo apt install libasound2-dev
sudo apt install libffi-dev
sudo apt install autoconf

(3)为了编译大版本号为N的Java代码,还需下载大版本号至少为N-1的,已经编译好的JDK

1
sudo apt install openjdk-11-jdk

四、进行编译

(1)配置

1
bash configure [options]
1
2
3
4
# 参数说明
--with-debug-level=<level>:设置编译级别,可选值为release、fastbug、slowdebug,越往后优化的措施越少,带的调试信息就越多。默认为release。

--with-jvm-variants=<variant>:编译特定模式的HotSpot虚拟机,可以多个模式并存,可选值为server、client、minimal、core、zero、custom。

比如

1
bash configure --with-debug-level=release --with-jvm-variants=server

configure的作用包括:依赖项检查、参数配置、构建输出目录结构等多项职责

配置完成后,会在build目录下生成如linux-x86_64-server-release的子目录

(2)编译JDK

1
make images

完成后会在build/linux-x86_64-server-release/下生成images等目录

【注意】多次编译后或目录结构成功产生后,需要再修改配置时,要先清理目录,才能确保新的配置生效。指令如下

1
2
make clean
make dist-clean

(3)复制JDK到JAVA_HOME即可使用

编译完成后,进入OpenJDK源码的build/linux-x86_64-server-release/jdk目录就可看到编译结果,把它复制到JAVA_HOME(一般在usr/lib/jvm)就可作为一个完整的JDK使用。

1.6 在Clion中调试源码

首先需要编译好的代码。此处再示范一次

(1)bash configure --with-debug-level=release --with-jvm-variants=server

image-20211224145802475

(2)make images

(3)

如何“New CMake Project from Sources”

https://www.jetbrains.com/help/clion/creating-new-project-from-scratch.html#import-prj

如何调试openjdk12的代码

https://blog.51cto.com/u_330478/4249643



----------- 本文结束 -----------




0%