JDK13的新特性:AppCDS詳解

簡介

AppCDS的全稱是Application Class-Data Sharing。主要是用來在不一樣的JVM中共享Class-Data信息,從而提高應用程序的啓動速度。java

一般來講,若是要執行class字節碼,JVM須要執行下面的一些步驟:給定一個類的名字,JVM須要從磁盤上面找到這個文件,加載,並驗證字節碼,最後將它加載進來。git

若是JVM啓動的時候須要加載成百上千個class,那麼須要的就不是一個小數目了。github

對於打包好的jar包來講,只要jar的內容不變,那麼jar包中的類的數據始終是相同的。JVM在啓動時候每次都會運行相同的加載步驟。app

更多內容請訪問 www.flydean.com

AppCDS的做用就是將這些可以共享的數據歸類成一個存儲文件,在不一樣的JVM中共享。調試

基本步驟

對AppCDS有了基本的瞭解以後,咱們講一下AppCDS的大概工做流程:日誌

  1. 選擇要歸檔的class,並建立一個class的列表,用在歸檔中。( -XX:DumpLoadedClassList)
  2. 建立歸檔文件(-Xshare:dump和-XX:SharedArchiveFile)
  3. 使用歸檔文件(-Xshare:on 和 -XX:SharedArchiveFile)

新的JVM可使用歸檔文件來啓動,從而減小了class加載的步驟。同時加載到內存中的區域甚至能夠在其餘的JVM實例中共享。從而極大的提升了JVM的啓動速度。code

下面咱們從JDK class文件歸檔和應用程序class文件歸檔兩個方面來說解AppCDS的具體使用。server

JDK class文件歸檔

最簡單的AppCDS的例子就是歸檔JDK的class文件。JDK12,JDK13默認狀況下已經開啓了AppCDS的支持。若是須要停用,咱們能夠添加 -Xshare:off。內存

下面的例子專門用於JDK10和JDK11。get

建立JDK class-data archive

咱們可使用-Xshare:dump來建立JVM啓動時候默認加載的Class-Data:

java -Xshare:dump -XX:SharedArchiveFile=/tmp/sharedarchive.jsa

上面咱們添加了參數-XX:SharedArchiveFile,由於默認狀況下java shared archive file文件會建立在JAVA_HOME/lib/server/下面,這個是須要root權限才能寫入的。爲了方便起見,咱們手動指定了一個有讀寫權限的目錄。

生成的文件大概有12M,接下來咱們就可使用這個JSA文件來啓動java程序了。

使用JDK class-data archive啓動應用程序

咱們先寫一個能夠運行的CDS hello world:

public class CDSHelloWorld {
    public static void main(String[] args) {
        System.out.println("CDS Hello World");
    }
}

編譯以後,咱們運行下面的命令來使用上面建立的jsa文件:

java -Xlog:class+load:file=/tmp/sharedarchive.log  -XX:SharedArchiveFile=/tmp/sharedarchive.jsa --enable-preview CDSHelloWorld

上面的命令添加了兩個運行時參數:

-XX:SharedArchiveFile表示使用哪一個具體的jsa文件來運行java程序。

-Xlog:class+load:file主要是作調試用的,將會把JVM的class load信息輸出到指定的文件中,方便咱們查看。這個unified logging特性是在JDK9中添加的,後面咱們也會詳細介紹。

簡單查看一下生產的log文件:

[0.010s][info][class,load] opened: /Library/Java/JavaVirtualMachines/jdk-14.0.1.jdk/Contents/Home/lib/modules
[0.017s][info][class,load] java.lang.Object source: shared objects file
[0.017s][info][class,load] java.io.Serializable source: shared objects file
[0.017s][info][class,load] java.lang.Comparable source: shared objects file
...
[0.056s][info][class,load] CDSHelloWorld source: file:/Users/learn-java-base-9-to-14/java-13/target/classes/

從生成的日誌文件咱們能夠看到,除了本身寫的java文件,其餘的java class都是從shared objects file中加載的。

運行時間對比

咱們能夠簡單的使用time命令來對兩種狀況進行一下對比,看具體的運行時間差異:

time  java -Xlog:class+load:file=/tmp/sharedarchive.log  -XX:SharedArchiveFile=/tmp/sharedarchive.jsa --enable-preview CDSHelloWorld 
CDS Hello World
java -Xlog:class+load:file=/tmp/sharedarchive.log  --enable-preview   

0.06s user 
0.06s system 
77% cpu 
0.164 total
time java  --enable-preview CDSHelloWorld 
CDS Hello World
java --enable-preview CDSHelloWorld  

0.09s user 
0.06s system 
66% cpu 
0.222 total

HelloWorld只是一個簡單的例子,可能二者的區別還不是特別明顯。

若是是大型的項目,處理JDK自帶的class以外,咱們還能夠將項目中共享的模塊作成jsa文件,從而提高啓動速度。

應用程序class文件歸檔

應用程序class文件歸檔和上面講的JDK class文件歸檔很相似。基本步驟就是:1.列出運行應用程序時須要加載的class文件。2.將這class文件歸檔。

在JDK13以前,咱們須要兩步才能生成jsa文件。在JDK13以後,只須要一個命令就好了。

生成應用程序加載class的列表

咱們可使用XX:DumpLoadedClassList來生成應用程序加載class的列表:

java -XX:DumpLoadedClassList=/tmp/classes.lst --enable-preview CDSHelloWorld

咱們能夠獲得相似下面的class文件列表:

java/lang/Object
java/io/Serializable
java/lang/Comparable
java/lang/CharSequence
java/lang/constant/Constable
java/lang/constant/ConstantDesc

使用class文件列表生成jsa文件

有了class文件列表,咱們就能夠生成jsa文件了:

java -Xshare:dump -XX:SharedArchiveFile=/tmp/sharedarchive.jsa -XX:SharedClassListFile=/tmp/classes.lst  --enable-preview CDSHelloWorld

跟以前的例子同樣,只不過多了一個-XX:SharedClassListFile參數。

JDK13的新用法

在JDK13,一切都變得簡單了,只須要一個-XX:ArchiveClassesAtExit就好:

java -XX:ArchiveClassesAtExit=/tmp/sharedarchive.jsa  --enable-preview CDSHelloWorld

JVM將會在退出時生成jsa文件。

總結

AppCDS是一個新特性,在特別關注java啓動時間的狀況下能夠考慮使用。

本文的例子https://github.com/ddean2009/learn-java-base-9-to-20

本文做者:flydean程序那些事

本文連接:http://www.flydean.com/jdk13-appcds/

本文來源:flydean的博客

歡迎關注個人公衆號:程序那些事,更多精彩等着您!

相關文章
相關標籤/搜索