日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

java 位运算取8位_Java 9 AOT 试用:仅支持 64 位 Linux和java.base 模块编译

發(fā)布時(shí)間:2025/3/11 linux 54 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 位运算取8位_Java 9 AOT 试用:仅支持 64 位 Linux和java.base 模块编译 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Java 9 引入了 aot 編譯方式,能夠?qū)?class 文件直接編譯成可執(zhí)行二進(jìn)制文件。目前 Java 9 的 early access 版本已經(jīng)提供了編譯工具,讓我們來看看它的功能吧。

注意:按照 JEP 295 描述,目前版本的 AOT,僅支持 64 位 Linux 操作系統(tǒng)。

jaotc 使用

首先需要下載最新的Java 9(JDK),本文編寫時(shí),最新版本是Build 152。下載好的JDK 只需要解壓即可使用,特別注意使用前設(shè)置好 PATH和JAVA_HOME兩個(gè)環(huán)境變量,避免和機(jī)器上已經(jīng)安裝的 JDK 混淆。筆者安裝到了 $HOME/bin/jdk-9,并設(shè)置了:

export PATH=~/bin/jdk-9/bin:$PATH

export JAVA_HOME=~/bin/jdk-9

需要使用jaotc,首先需要有個(gè)測試類,首先從 Hello World 開始:

class HelloWorld {

public static void main(String[] args) {

System.out.println("Hello World!");

}

}

代碼非常簡單,但是在執(zhí)行 jaotc 之前,還需要將其編譯成 class 文件,直接使用 javac 即可:

$ javac HelloWorld.java

執(zhí)行成功之后,會(huì)生成 HelloWorld.class 文件。此時(shí)直接使用 java 命令,已經(jīng)可以正常運(yùn)行這個(gè)類:

$ java HelloWorld

Hello World!

這時(shí),就可以基于這個(gè) class 文件,通過jaotc命令將其編譯成二進(jìn)制文件了。

$ jaotc --output libHelloWorld.so HelloWorld.class

如果一切正常,會(huì)生成 libHelloWorld.so 文件。

如果出現(xiàn)類似Exception in thread "main" java.lang.UnsatisfiedLinkError: /home/babydragon/bin/jdk-9/lib/libjelfshim.so: libelf.so.1: 無法打開共享對(duì)象文件: 沒有那個(gè)文件或目錄的錯(cuò)誤,是因?yàn)閖aotc需要依賴 libelf 動(dòng)態(tài)鏈接庫來創(chuàng)建 elf 文件(最終生成的 libHelloWorld.so 文件是一個(gè)靜態(tài)鏈接的 elf 文件)。筆者使用的是 Gentoo 系統(tǒng),需要安裝 dev-libs/elfutils 包,以提供 libelf.so 這個(gè)動(dòng)態(tài)連接庫。安裝之后可以通過ldd命令進(jìn)行確認(rèn):

$ ldd $JAVA_HOME/lib/libjelfshim.so

linux-vdso.so.1 (0x00007ffd001f3000)

libelf.so.1 => /usr/lib64/libelf.so.1 (0x00007f25ea2ce000)

libc.so.6 => /lib64/libc.so.6 (0x00007f25e9f35000)

libz.so.1 => /lib64/libz.so.1 (0x00007f25e9d1d000)

/lib64/ld-linux-x86-64.so.2 (0x0000562318d51000)

前面通過jaotc命令成功生成了 libHelloWorld.so。雖然命令里面參照 JEP 295 的示例將生成的文件后綴設(shè)置成了 so,但如果使用ldd命令查看,會(huì)發(fā)現(xiàn)它其實(shí)是一個(gè)靜態(tài)鏈接庫:

$ ldd libHelloWorld.so

statically linked

通過nm命令,可以看見代碼段中的函數(shù)入口:

$ nm libHelloWorld.so

0000000000002420 t HelloWorld.()V

0000000000002520 t HelloWorld.main([Ljava/lang/String;)V

最后,需要執(zhí)行時(shí)需要通過參數(shù)-XX:AOTLibrary參數(shù)指定需要加載的經(jīng)過 aot 預(yù)編譯好的共享庫文件:

java -XX:AOTLibrary=./libHelloWorld.so HelloWorld

注意:雖然已經(jīng)將整個(gè) HelloWorld 類都通過 jaotc 編譯成共享庫文件,運(yùn)行時(shí)仍然需要依賴原有的 HelloWorld.class 文件。

此時(shí)執(zhí)行的輸出,和之前不使用 AOT 的輸出完全相同。

來把大的——將 java.base 模塊編譯成 AOT 庫

JEP 295 中已經(jīng)說明,在 Java 9 初始發(fā)布的時(shí)候,只保證 java.base 模塊可以被編譯成 AOT 庫。

繼續(xù)參照 JEP 295,創(chuàng)建 java.base-list.txt 文件,內(nèi)容主要是排除一些編譯有問題的方法,具體內(nèi)容參照原文。

然后執(zhí)行命令:

jaotc -J-XX:+UseCompressedOops -J-XX:+UseG1GC -J-Xmx4g --compile-for-tiered --info --compile-commands java.base-list.txt --output libjava.base-coop.so --module java.base

在筆者的機(jī)器上(i7-6600U + 16G 內(nèi)存 + 256G NVMe SSD),排除上述方法之后,編譯時(shí)間大約為 9 分多鐘。

48878 methods compiled, 4 methods failed (497771 ms)

Parsing compiled code (1126 ms)

Processing metadata (15811 ms)

Preparing stubs binary (0 ms)

Preparing compiled binary (104 ms)

Creating binary: libjava.base-coop.o (5611 ms)

Creating shared library: libjava.base-coop.so (7306 ms)

Total time: 542536 ms

完成之后,就可以使用 AOT 版本的 java.base 模塊:

java -XX:AOTLibrary=java_base/libjava.base-coop.so,./libHelloWorld.so HelloWorld

同樣,針對(duì) AOT,jvm 也新增了參數(shù)打印哪些方法是通過加載 AOT 預(yù)編譯庫執(zhí)行。

java -XX:+PrintAOT -XX:AOTLibrary=java_base/libjava.base-coop.so,./libHelloWorld.so HelloWorld

輸出可以和不使用 java.base 的 AOT 進(jìn)行比較,發(fā)現(xiàn)不使用 java.base 的 AOT 庫,只能會(huì)加載 libHelloWorld.so 中對(duì)應(yīng)的方法。

$ java -XX:+PrintAOT -XX:AOTLibrary=./libHelloWorld.so HelloWorld

11 1 loaded ./libHelloWorld.so aot library

105 1 aot[ 1] HelloWorld.()V

105 2 aot[ 1] HelloWorld.main([Ljava/lang/String;)V

Hello World!

$ java -XX:+PrintAOT -XX:AOTLibrary=java_base/libjava.base-coop.so,./libHelloWorld.so HelloWorld

13 1 loaded java_base/libjava.base-coop.so aot library

13 2 loaded ./libHelloWorld.so aot library

[Found [Z in java_base/libjava.base-coop.so]

[Found [C in java_base/libjava.base-coop.so]

[Found [F in java_base/libjava.base-coop.so]

[Found [D in java_base/libjava.base-coop.so]

[Found [B in java_base/libjava.base-coop.so]

[Found [S in java_base/libjava.base-coop.so]

[Found [I in java_base/libjava.base-coop.so]

[Found [J in java_base/libjava.base-coop.so]

31 1 aot[ 1] java.lang.Object.()V

31 2 aot[ 1] java.lang.Object.finalize()V

...

輸出太長,節(jié)選部分輸出,我們可以看見 java 基礎(chǔ)類及其方法都通過 AOT 的方式進(jìn)行加載。

實(shí)用嗎?

目前 AOT 的局限有:

僅支持 64 位 Linux 操作系統(tǒng):這個(gè)問題不是很大,畢竟大部分線上服務(wù)器都能夠滿足;

操作系統(tǒng)需要預(yù)裝 libelf 庫,以確保能夠生成 elf 文件:這個(gè)問題也不大,僅生成時(shí)需要;

AOT 編譯和執(zhí)行環(huán)境需要相同:畢竟是二進(jìn)制文件,引入了平臺(tái)相關(guān)性;

Java 9 最初發(fā)布時(shí),只支持 java.base 模塊可以編譯成 AOT 庫;

目前只支持 G1 和 Parallel GC 兩種 GC 方式:前面沒有提到,AOT 編譯時(shí)的 JVM 參數(shù)和運(yùn)行時(shí)需要相同,也包括 GC 方式,也就是說如果用了 AOT,JVM 實(shí)際運(yùn)行時(shí)也只能使用這兩種 GC 方式之一;

可能會(huì)無法編譯通過動(dòng)態(tài)生成 class 文件或者修改字節(jié)碼的 java 代碼(如 lambda 表達(dá)式、反射調(diào)用等):這個(gè)可能會(huì)比較坑,后面會(huì)講到;

JVM 運(yùn)行時(shí)參數(shù)設(shè)置必須和 AOT 庫編譯時(shí)相同;

AOT 可能帶來的好處,是 JVM 加載這些已經(jīng)預(yù)編譯成二進(jìn)制庫之后,可以直接調(diào)用,而無需再將其運(yùn)行時(shí)編譯成二進(jìn)制碼。理論上,AOT 的方式,可以減少 JIT 帶來的預(yù)熱時(shí)間,減少 Java 應(yīng)用長期給人帶來的“第一次運(yùn)行慢”感覺。

不過,本文使用的 HelloWorld 過于簡單,無法通過對(duì)比得出 AOT 是否可以減少 JVM 初始化時(shí)間。筆者嘗試對(duì)一個(gè)小型 springboot 應(yīng)用進(jìn)行 AOT 化,但是 springboot 框架本身無法在 Java 9 中運(yùn)行。同時(shí)直接對(duì) spring-core 的 jar 包執(zhí)行 jaotc 也因?yàn)楦鞣N依賴問題而失敗。

經(jīng)過各種嘗試,目前 Java 9 的 AOT 功能還處于很初步的階段:

缺少 maven 等管理工具集成,無法方便的對(duì)項(xiàng)目指定 jar 或者 class 文件比構(gòu)建 AOT 庫;

大型框架還沒有官方支持,構(gòu)建 AOT 庫難度比較高;

大型框架如果直接提供 AOT 庫,可能會(huì)因?yàn)橛商囟ㄆ脚_(tái)構(gòu)建,而在本地?zé)o法使用;

期待 Java 9 正式發(fā)布的時(shí)候,能夠?qū)?AOT 有更好的支持。

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的java 位运算取8位_Java 9 AOT 试用:仅支持 64 位 Linux和java.base 模块编译的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。