前面提到了一些JDK13的新特性捷雕,但是還是有一些覆蓋不全的地方,可能會(huì)存在一些問(wèn)題壶熏,這里嘗試回答這些問(wèn)題浦译。
AppCDS
在多個(gè)JVM實(shí)例運(yùn)行的時(shí)候帽哑,這幾個(gè)實(shí)例之間是不是共享class數(shù)據(jù)祝拯?
AppCDS背后的設(shè)計(jì)是只需要?jiǎng)?chuàng)建一次class-data的歸檔她肯,然后共享它,后續(xù)JVM不需要重新創(chuàng)建而已康嘉。另外AppCDS只是減少了類加載的時(shí)間籽前,在程序運(yùn)行的時(shí)候,并沒(méi)有共享class信息肄梨。
但其實(shí)從另外一方面挠锥,在運(yùn)行的時(shí)候創(chuàng)建的對(duì)象肯定是相互獨(dú)立的,而class信息粱侣,如果加載也是從共享的歸檔加載的蓖宦,一定程度上也算是共享了class的信息。
class-data指的具體是什么東西柠偶?
根據(jù)命令行指定睬关,-XX:DumpLoadedClassList,或者名字该肴,存儲(chǔ)的就是class的信息藐不。
如果當(dāng)class信息變化的時(shí)候呢,class-data相當(dāng)于緩存的作用涎嚼,這樣肯定存在數(shù)據(jù)不一致的問(wèn)題法梯?
其實(shí),這個(gè)應(yīng)該是什么時(shí)候class-data會(huì)失效立哑,如何檢測(cè)到class-data會(huì)失效铛绰。
為了檢測(cè)到class-path不匹配,在創(chuàng)建歸檔的時(shí)候JVM嵌入了列出class-path下的內(nèi)容字符串捂掰,當(dāng)我們的應(yīng)用使用歸檔的時(shí)候这嚣,JVM比較實(shí)際的類路徑內(nèi)容,和嵌入的類路徑內(nèi)容吏垮,只有嵌入的路徑是實(shí)際路徑的前綴才進(jìn)行運(yùn)行卧土。
To have a decent chance at detecting a class path mismatch, the JVM embeds the string that lists the class path content in the archive when creating it. When you launch the app with the archive, the JVM compares the actual class path with the embedded one and only launches if the latter is a prefix of the former.
另外既然是我們手動(dòng)創(chuàng)建的歸檔內(nèi)容,那么最好創(chuàng)建正確的歸檔旅敷,JDK13提供了選項(xiàng)颤霎。-XX:ArchiveClassesAtExit=app-cds.jsa 退出的時(shí)候自動(dòng)創(chuàng)建歸檔友酱,那么更新,應(yīng)用之后重啟一下缔杉。
如果兩個(gè)應(yīng)用在使用一個(gè)歸檔或详,結(jié)果這個(gè)時(shí)候歸檔更新了郭计,程序會(huì)出現(xiàn)問(wèn)題嗎椒振?
我覺(jué)得程序運(yùn)行的時(shí)候都是把文件先加載到內(nèi)存的,不可能每次從文件系統(tǒng)上再讀一次庐杨。磁盤(pán)上的變化不會(huì)影響內(nèi)存中的內(nèi)容夹供。
AppCDS主要減少了應(yīng)用加載的時(shí)間罩引,那么使用 -Xverify:none
或-noverify
會(huì)不會(huì)有相似的效果呢枝笨?
-Xverify:none
或-noverify
在JDK13中標(biāo)記為丟棄,計(jì)劃未來(lái)移除剔桨,https://bugs.openjdk.java.net/browse/JDK-8218003
看下實(shí)際運(yùn)行的效果:
首先打包下歸檔:
/Library/Java/JavaVirtualMachines/jdk-13.jdk/Contents/Home/bin/java -Xshare:dump -XX:SharedClassListFile=classes.lst -XX:SharedArchiveFile=jdk13-custom.jsa --class-path target/HelloApp.jar
/Library/Java/JavaVirtualMachines/jdk-13.jdk/Contents/Home/bin/java -XX:SharedArchiveFile=jdk13-custom.jsa -jar target/HelloApp.jar
time /Library/Java/JavaVirtualMachines/jdk-13.jdk/Contents/Home/bin/java -Xshare:off -noverify -XX:SharedArchiveFile=jdk13-custom.jsa -jar target/HelloApp.jar
time /Library/Java/JavaVirtualMachines/jdk-13.jdk/Contents/Home/bin/java -Xshare:off -XX:SharedArchiveFile=jdk13-custom.jsa -jar target/HelloApp.jar
time /Library/Java/JavaVirtualMachines/jdk-13.jdk/Contents/Home/bin/java -XX:SharedArchiveFile=jdk13-custom.jsa -jar target/HelloApp.jar
可以明顯的看出來(lái)洒缀,AppCDS還是最快的欺冀。
ZGC
在ZGC中有個(gè)隐轩,relocation的階段,這個(gè)階段把對(duì)象重新分配位置瘫俊,但是這時(shí)悴灵,并沒(méi)有重寫(xiě)內(nèi)存引用,會(huì)不會(huì)讀到垃圾對(duì)象川尖?
其它的垃圾收集器都是使用store barriers茫孔,ZGC使用load barriers庐船,用于跟蹤內(nèi)存嘲更。在從堆中加載數(shù)據(jù)的時(shí)候,檢查引用的元數(shù)據(jù)位篓冲,然后在引用上執(zhí)行處理
lock->unlock->read->load 讀內(nèi)存
use->assign->store->write 寫(xiě)內(nèi)存
- remap代表對(duì)象是否被重新映射到新的位置
- 第一次relocation壹将,根據(jù)標(biāo)記判斷是否被移動(dòng)到了新的位置
- 如果是毛嫉,判斷是否真的在重新分配的區(qū)域
- 不是:重新分配,返回引用
- 是暴区,更新引用到新的位置辛臊,然后返回
- 更新remap位,返回引用
- 如果是毛嫉,判斷是否真的在重新分配的區(qū)域
relocate objects from fragmented memory areas to free areas in a more compact format
ZGC bypasses this cost with the fact that exactly one of the four metadata bits will be 1.
最后
這次問(wèn)題先到這里伐割,主要起到拋磚引玉的作用隔心,更深的細(xì)節(jié)還需要自己挖掘啊尚胞。