WebLogic Server 12.2.1に密かに追加されたクラスデータ共有機能 #jpoug
はじめに
この記事はJPOUG Advent Calendarの10日目です。
先日10/19にWebLogic Server(以下、WLS)勉強会で、WLS 12.2.1.0/12.2.1.1のマイナーな新機能などを取り上げました。
"おそらく"と言うのは、WLSのクラスデータ共有機能については、今のところ公式ドキュメントに記載がないためです。
そのため正式にはサポートされておらず、本記事で記載する内容は、将来的に予告なく変更されたり廃止される可能性もありますので、念のためご注意・ご了承ください。
確認した環境は次の通りです。
クラスデータ共有とは
クラスデータ共有(CDS)は、HotSpot JDKの機能*4として、実はJ2SE 5.0の頃からあります。
詳細はドキュメントを確認いただきたいのですが、アプリケーションの起動時間やメモリフットプリントを短縮するために、複数のJVMでクラスデータを利用できるよう共有アーカイブを作成・利用します。
ただ、通常のCDSは、HotSpot Client VMかつシリアルガベージコレクタ環境でのみのサポートされるもので、今の時代となっては実質的に使われないでしょう。
Oracle JDK 8u40ではこのCDSを拡張して、多くのアプリケーション環境で利用できるように、商用機能*5の一つとして、アプリケーションクラスデータ共有(AppCDS)が導入されました。ツールドキュメントには実験的と記載があるのですが、実際はそんなことはないようです。
今回紹介するWLSのクラスデータ共有は、実際にはこちらのAppCDSを利用することになります。
WLSでのAppCDSの利用方法
それでは、WLSでAppCDSを利用してみましょう。
まずはWLSをインストールし、ドメインを作成してください。
インストール手順やドメイン作成手順は割愛します。
クラスリストの作成
ターミナルからドメインディレクトリに移動し、WLSを起動するためのスクリプト(startWebLogic.sh)に、引数「generateClassList」を加えて実行します。
$ cd ~/weblogic/wls12212_dev/user_projects/domains/base_domain $ ./bin/startWebLogic.sh generateClassList
すると、通常のWLS起動オプションに次のJVMオプションが加わって実行されます。(改行を入れています)
-XX:+UnlockCommercialFeatures -XX:+IgnoreEmptyClassPaths -XX:DumpLoadedClassList=/Users/takahiro/weblogic/wls12212_dev/user_projects/domains/base_domain/WebLogic.classlist -XX:+UseAppCDS
WLSがRUNNINGで起動したことを確認したら、一旦Ctrl+Cなどで止めてみましょう。
ドメインディレクトリ直下にWebLogic.classlistが作成されていることが確認できます。
$ ls -l total 1352 -rw-r----- 1 takahiro staff 671492 12 10 20:24 WebLogic.classlist drwxr-x--- 3 takahiro staff 102 12 7 01:01 autodeploy drwxr-x--- 20 takahiro staff 680 12 7 01:01 bin drwxr-x--- 3 takahiro staff 102 12 7 01:01 common drwxr-x--- 11 takahiro staff 374 12 7 01:01 config drwxr-x--- 3 takahiro staff 102 12 7 01:01 console-ext -rw-r----- 1 takahiro staff 438 12 10 20:24 derby.log -rw-r----- 1 takahiro staff 104 12 10 20:24 derbyShutdown.log -rw-r----- 1 takahiro staff 139 12 10 20:24 edit.lok -rw-r----- 1 takahiro staff 327 6 13 07:29 fileRealm.properties drwxr-x--- 14 takahiro staff 476 12 7 01:01 init-info drwxr-x--- 3 takahiro staff 102 12 7 01:01 lib drwxr-x--- 4 takahiro staff 136 12 7 01:01 nodemanager drwxr-x--- 3 takahiro staff 102 12 7 01:01 orchestration drwxr-x--- 7 takahiro staff 238 12 7 01:01 security drwxr-x--- 3 takahiro staff 102 12 7 01:01 servers -rwxr-x--- 1 takahiro staff 287 12 7 01:01 startWebLogic.sh
中身はテキスト形式で、ロードされたクラスが記録されています。
大きいので、最初と最後の10行だけ見てみましょう。
$ head WebLogic.classlist java/lang/Object java/lang/String java/io/Serializable java/lang/Comparable java/lang/CharSequence java/lang/Class java/lang/reflect/GenericDeclaration java/lang/reflect/AnnotatedElement java/lang/reflect/Type java/lang/Cloneable
$ tail WebLogic.classlist weblogic/messaging/common/PrivilegedActionUtilities$4 weblogic/rmi/server/UnicastRemoteObject weblogic/rmi/server/RemoteServer weblogic/rmi/server/RemoteObject weblogic/messaging/dispatcher/DispatcherWrapperState weblogic/work/concurrent/services/PartitionConcurrrentManagedObjectFactory$1 weblogic/store/admin/JMXUtils$2 weblogic/store/io/file/StoreFile$1CloseChannels weblogic/store/admin/JMXUtils$4 weblogic/ldap/LDAPExecuteRequest
共有アーカイブの作成
次に前項で作成されたWebLogic.classlistを使って、共有アーカイブを作成するためにgenerateArchive.shを実行します。
$ ./bin/generateArchive.sh
実際には、次のようなjavaコマンドが実行されます。(改行を入れておきます)
/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/bin/java -XX:+UnlockCommercialFeatures -XX:+UnlockDiagnosticVMOptions -Xshare:dump -XX:+UseAppCDS -XX:+IgnoreEmptyClassPaths -XX:+TraceClassPaths -XX:+IgnoreUnverifiableClassesDuringDump -XX:SharedArchiveFile=/Users/takahiro/weblogic/wls12212_dev/user_projects/domains/base_domain/WebLogic.jsa -XX:SharedClassListFile=/Users/takahiro/weblogic/wls12212_dev/user_projects/domains/base_domain/WebLogic.classlist
このコマンドの出力は非常に多くなるため、最後の部分のみ記載します。
Rewriting and linking classes: done Number of classes 15293 instance classes = 15279 obj array classes = 6 type array classes = 8 Calculating fingerprints ... done. Removing unshareable information ... done. Shared Lookup Cache Table Buckets = 8216 bytes Shared Lookup Cache Table Body = 617592 bytes ro space: 48183744 [ 40.5% of total] out of 122683392 bytes [39.3% used] at 0x0000000800000000 rw space: 62089888 [ 52.2% of total] out of 157286400 bytes [39.5% used] at 0x0000000807500000 md space: 8538968 [ 7.2% of total] out of 28311552 bytes [30.2% used] at 0x0000000810b00000 mc space: 34053 [ 0.0% of total] out of 6291456 bytes [ 0.5% used] at 0x0000000812600000 total : 118846653 [100.0% of total] out of 314572800 bytes [37.8% used]
そして、共有アーカイブとしてWebLogic.jsaが作成されたことが確認できます。
$ ls -l total 233512 -rw-r----- 1 takahiro staff 671492 12 10 20:24 WebLogic.classlist -r--r----- 1 takahiro staff 118865920 12 10 20:24 WebLogic.jsa drwxr-x--- 3 takahiro staff 102 12 7 01:01 autodeploy drwxr-x--- 20 takahiro staff 680 12 7 01:01 bin drwxr-x--- 3 takahiro staff 102 12 7 01:01 common drwxr-x--- 11 takahiro staff 374 12 7 01:01 config drwxr-x--- 3 takahiro staff 102 12 7 01:01 console-ext -rw-r----- 1 takahiro staff 438 12 10 20:24 derby.log -rw-r----- 1 takahiro staff 104 12 10 20:24 derbyShutdown.log -rw-r----- 1 takahiro staff 139 12 10 20:24 edit.lok -rw-r----- 1 takahiro staff 327 6 13 07:29 fileRealm.properties drwxr-x--- 14 takahiro staff 476 12 7 01:01 init-info drwxr-x--- 3 takahiro staff 102 12 7 01:01 lib drwxr-x--- 4 takahiro staff 136 12 7 01:01 nodemanager drwxr-x--- 3 takahiro staff 102 12 7 01:01 orchestration drwxr-x--- 7 takahiro staff 238 12 7 01:01 security drwxr-x--- 3 takahiro staff 102 12 7 01:01 servers -rwxr-x--- 1 takahiro staff 287 12 7 01:01 startWebLogic.sh
共有アーカイブを利用してWLSを起動
では、仕上げに前項で作成されたWebLogic.jsaを利用してWLSを起動しましょう。
startWebLogic.shの引数に「useArchive」を加えます。
$ ./bin/startWebLogic.sh useArchive
今度は、通常のWLS起動オプションに次のJVMオプションが加わって実行されます*6。(改行を入れています)
-XX:+UnlockCommercialFeatures -Xshare:auto -XX:+UseAppCDS -XX:+IgnoreEmptyClassPaths -XX:SharedArchiveFile=/Users/takahiro/weblogic/wls12212_dev/user_projects/domains/base_domain/WebLogic.jsa -showversion
これで共有アーカイブを利用できるようになったはずです。
…と思ったのですが「-verbose:class」を付加して確認すると、共有アーカイブではなく、通常のjarファイルからロードされています。
何かがおかしいはずなので、上記の「-Xshare:auto」を「-Xshare:on」になるようstartWebLogic.shを修正してから実行すると、次のエラーで異常終了しました。
An error has occurred while processing the shared archive file. Tool agent requires sharing to be disabled. Error occurred during initialization of VM Unable to use shared archive.
エージェント利用時は共有アーカイブを無効にする必要があるようですね。ここで思い出しました。
WLS 12.2.1には動的デバッグパッチ機能が追加されており、デフォルトで起動オプションに「-javaagent:$WL_HOME/server/lib/debugpatch-agent.jar」が追加されます。
最初のスライドのP18に記載していますが、これを無効にすべくstartWebLogic.shの引数に「disableDebugPatches」を追加して実行してみましょう。
$ ./bin/startWebLogic.sh useArchive disableDebugPatches
「-verbose:class」の出力を確認すると、次のようにWLS関連のクラスも共有アーカイブから読み込まれるようになりました!*7
[Loaded weblogic.Server from shared objects file by sun/misc/Launcher$AppClassLoader]
それで、パフォーマンスは良くなったの?
マシンスペックなどにも大きく依存するでしょうし、オラクル製品はベンチマークを公開してはいけないポリシーだったはずなので、詳細は記載しませんが、今回の私の環境では、WLS起動時のパフォーマンスはかなり向上しました。
また、今回はWLS管理サーバだけで確認しましたが、1つのホスト・ドメイン内で複数のWLSインスタンスを起動する際には、メモリフットプリントも改善されることが期待できます。
まとめ
それではまとめです。
- WLS 12.2.1にはドキュメント未記載ですが、アプリケーションクラスデータ共有(AppCDS)を利用する機能が組み込まれています。
- AppCDSを利用すると、WLSの起動パフォーマンスの改善や、メモリフットプリントの向上が期待できます。
- 正式にリリースされた際には、ライセンスに注意しつつ検証して利用しましょう。
*1:マルチテナントなどは商用で使うにはWLS Enterprise Editionやオプションライセンスが必要となり、個人的には勉強会では取り上げにくいので省きました。
*2:10/19勉強会の夜間にちょうどリリースされたため、先のスライドには含められませんでしたが、このパッチセットは基本的にBug修正がメインのようなので、それほど目立った新機能は見当たりません。
*3:開発環境用としてのみ動作保証されているようです。
*4:同様のクラス共有機能はIBM JDKでも実装されています。
*5:つまり本番環境などで利用するにはライセンスが必要です。
*6:直接は関係ない「-showversion」も入ってます。