溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

使用aot的坑怎么解決

發(fā)布時(shí)間:2021-12-21 10:29:23 來(lái)源:億速云 閱讀:189 作者:iii 欄目:開(kāi)發(fā)技術(shù)

本篇內(nèi)容主要講解“使用aot的坑怎么解決”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“使用aot的坑怎么解決”吧!

啟動(dòng)參數(shù)固定化

jaotc可以通過(guò)加-J參數(shù)來(lái)指定jvm的啟動(dòng)參數(shù)。我們嘗試使用cms來(lái)編譯一下庫(kù)文件。

jaotc   -J-XX:+UseConcMarkSweepGC --output libtest.so AotTest.class

執(zhí)行的結(jié)果會(huì)有兩條信息。

Java HotSpot(TM) 64-Bit Server VM warning: Option UseConcMarkSweepGC was deprecated in version 9.0 and will likely be removed in a future release.
Error occurred during initialization of VM
JVMCI Compiler does not support selected GC: concurrent mark sweep gc

第一條是cms已經(jīng)標(biāo)記為廢棄。第二條是jvmci不支持cms。按照官方文檔上講,現(xiàn)在的aot支持ps和g1。其他的并不支持。我們下面試試ps,因?yàn)楝F(xiàn)在默認(rèn)已經(jīng)是g1了。

jaotc   -J-XX:+UseParallelGC --output libtest.so AotTest.class

發(fā)現(xiàn)是成功的。

啟動(dòng)的參數(shù)需要固定化這也就是說(shuō)你有兩種配置,就得先用jaotc去編譯出兩個(gè)版本的庫(kù),在用的時(shí)候進(jìn)行選擇。

編譯參數(shù)和啟動(dòng)參數(shù)要一致

我們基于上面產(chǎn)生ps的libtest.so,我們嘗試換個(gè)啟動(dòng)參數(shù)。

java  -XX:+UseConcMarkSweepGC -XX:AOTLibrary=./libtest.so AotTest
java  -XX:+UseParallelGC -XX:AOTLibrary=./libtest.so AotTest
java  -XX:+UseG1GC -XX:AOTLibrary=./libtest.so AotTest

你會(huì)發(fā)現(xiàn)上面三個(gè)啟動(dòng)參數(shù)都會(huì)執(zhí)行正確,并沒(méi)有報(bào)錯(cuò)。是不是感覺(jué)違背了官方講的編譯和啟動(dòng)一致的這個(gè)要求。這里介紹一個(gè)參數(shù)。

-XX:+PrintAOT

這個(gè)參數(shù)可以打出使用aot的klasses和method。我們下面再試試G1(庫(kù)是上面指定了ps的)。

java  -XX:+UseG1GC -XX:+PrintAOT -XX:AOTLibrary=./libtest.so AotTest

我們會(huì)發(fā)現(xiàn)有不一樣的輸出。

Shared file ./libtest.so error: used 'parallel gc' is different from current 'g1 gc'
     7    1     skipped ./libtest.so  aot library

這里會(huì)有一個(gè)錯(cuò)誤提示,說(shuō)libtest.so是使用了ps和現(xiàn)在用的g1不一樣。跳過(guò)了這個(gè)庫(kù)。然后對(duì)比一下ps的結(jié)果。

     12    1     loaded    ./libtest.so  aot library
   113    1     aot[ 1]   AotTest.<init>()V
   113    2     aot[ 1]   AotTest.main([Ljava/lang/String;)V

發(fā)現(xiàn)ps是可以打印出aot的方法的。

class文件是必須存在

我們既然編譯出可執(zhí)行文件了,那么class文件是不是可以不要了呢。答案是不行的。我們下面用一個(gè)復(fù)雜一點(diǎn)的案例。

public class TestB{
public static void main(String[] args) {
System.out.println("this is TestB");
}
}

準(zhǔn)備一個(gè)調(diào)用類。然后在另外一個(gè)文件里調(diào)用B。

public class AotTest{
   public static void main(String[] args) {
       TestB.main(null);
   }
}

我們這次把B單獨(dú)編譯成庫(kù),依舊使用。

jaotc --output  libB.so TestB.class

現(xiàn)在刪除TestB.class,再次執(zhí)行。我們發(fā)現(xiàn)會(huì)報(bào)下面的錯(cuò)誤。

Exception in thread "main" java.lang.NoClassDefFoundError: TestB
at AotTest.main(AotTest.java:3)
Caused by: java.lang.ClassNotFoundException: TestB
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 1 more

直接是NoClassDefFoundError。

aot的理解

jvm的整體流程沒(méi)有變化,aot的存在是替換了jit的部分,并不代表所有的數(shù)據(jù)都在生成的二進(jìn)制文件里。aot并不是把java變成了例如c那種的可執(zhí)行文件,他只是不需要?jiǎng)討B(tài)的編譯了,直接拿到現(xiàn)成的結(jié)果。

到此,相信大家對(duì)“使用aot的坑怎么解決”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI