SAP JVMについてOracle JDKとの違いを調べてみた(jvmmonという便利ツールは知っておきたい)

2年ぶりに調べたのでこちらにも書きました。

www.beex-inc.com

Oracle JVMとSAPJVMとの違いを聞かれたのですが、SAP製品インストールする時にダウンロードするくらいで、確かモニタリングの拡張してあるんだよな・・くらいの認識だったので、ちゃんと調べてみました。

前提として、情報のベースとしているのはこちらのヘルプです。これを普通に読むのが一番です。

https://help.sap.com/viewer/a0f332f9d5dd495a9543d620e9b084d2/7.5.10/en-US/47dc90b4ef17452289f9128b8c2bbd77.html

時間無い人や英語苦手な人は、この記事見てメリットあるかもしれません。

SAPJVMとは

ざっくり言えばSAPがSAP関連のサーバサイドソフトウェアを開発・運用・サポートしやすいようにOracleのHotspot VMとJDKから修正したものです。

特徴としてSAP製品が動くためOracleのものより多様なプラットフォームへ対応していることや、モニタリング機能が強化されていることがあります。

Oracle JDKとの変更点

もう少し詳しく見たい場合はヘルプのアーキテクチャのページを確認します。

まずは、Java SEのライブラリ群の変更から。

Soundの部分が削られて、Monitoringが追加されています。(もう少し古いバージョンではPrintingも削られていました)

>>引用元

それぞれのライブラリの中身にどんなものがあるのか知りたい方は、こちらのリンクからOracle Java本家のサイトに飛ぶのでリンク飛んで確認できます。

>>引用元

例えば今回削られたSoundはこちらです。 https://docs.oracle.com/javase/8/docs/technotes/guides/sound/index.html

次にJavaのVMの方の変更を見てみます。

一つ目としてOracle JDKがサポートしていないプラットフォームにも対応しています。PowerやSystem z、HP-UXのIA-64とか、実際に自分の手持ちの環境では試せないものばかりですが、SAPが動く環境です。

>>引用元

二つめとして、JIT ComplilerからはClientが削られています。Clientは起動が速かったり、利用するメモリ容量が少なく調整されたモードです。速度最適化されているServerモードのみが提供されています。

モニタリングの強化(jvmmon)

SAPJVMはモニタリングが強化されていてるとあって、色々拡張されているようなのです。

取れる項目が詳細になっていたり、大規模環境でもCPUやメモリの影響最小限にして情報取得できるようにしてあったり。そして、その集大成と言えるのがjvmmonというツールです。

対話形式CUIやGUIのインターフェースでSAP JVMの内部情報を取得できます。操作感覚的にはOracleに対するBRTOOLSのJava版です。

コマンドラインより、以下を起動すると。今現在起動しているVMの基本情報一覧が表示され、その後に対話プロンプトが表示されます。

./sapjvm_8/bin/jvmmon
   InstID/VmID       Pid       CPU[ms]   VmTag / Java arguments / working directory
+--------------+---------+-------------+--------------------------------------------

                     174          1280   Test /tmp
+--------------+---------+-------------+--------------------------------------------
                     176          1282   Test /tmp
+--------------+---------+-------------+--------------------------------------------
Pid =>174   # VMを選択する
$ # <-プロンプト

help コマンドでできることが表示されます。説明付きなのでそのまま貼っておきます。

$ help


__ Print commands: __________________________

  print class statistic                       - Prints class statistics of a VM
  print cluster memory information            - Prints information about the memory consumption of the cluster
  print codeblobs                             - Prints information about code blobs with specified name
  print debugging information                 - Prints information about the debugging state of a VM
  print detailed class statistic              - Prints detailed class statistics of a VM
  print dll info                              - Prints information about the loaded shared libraries of a VM
  print flight recorder                       - Prints part of the flight recorder of a VM
  print gc history                            - Prints the GC history of a VM
  print hs_err_info                           - Prints the hs-err-info of a VM
  print jit info                              - Prints information about JIT compiler and code cache
  print mallocstat                            - Prints malloc statistics
  print mallocstat internals                  - Prints internals for malloc statistics
  print memhist                               - Prints memory history
  print metaspace                             - Prints metaspace statistics
  print metaspace map                         - Prints a map of the metaspace.
  print performance information               - Prints information about the performance of a VM
  print signal handlers                       - Prints currently active signal handlers
  print stacktrace                            - Prints the stacks of all threads in a VM
  print symbol info                           - Prints information about symbols and interned strings of a VM
  print system information                    - Prints system information
  print system properties                     - Prints VM system properties
  print trace flags                           - Prints the active trace flags of a VM
  print virtualization info                   - Prints the platform virtualization info
  print vm compressed class space information - Prints information about the compressed class space of a VM
  print vm information                        - Prints information about a VM
  print vm memory information                 - Prints information about the memory consumption of a VM

__ Dump commands: ___________________________

  dump class statistic                        - Dumps class statistics of a VM
  dump codeblobs                              - Dumps information about code blobs with specified name
  dump detailed class statistic               - Dumps detailed class statistics of a VM
  dump dll info                               - Dumps information about the loaded shared libraries of a VM
  dump gc history                             - Dumps the GC history of a VM
  dump heap                                   - Dumps the heap of a VM
  dump heap with info                         - Dumps the heap and additional information describing the heap of a VM
  dump hs_err_info                            - Dumps the hs-err-info of a VM
  dump jit info                               - Dumps information about JIT compiler and code cache
  dump safepoint state                        - Dumps information about the safepoint state of the specified VM
  dump stacktrace                             - Dumps the stacks of all threads in a VM
  dump stacktrace with info                   - Dumps the stacks of all threads with additional information
  dump symbol info                            - Dumps information about symbols and interned strings of a VM

__ GC commands: _____________________________

  force gc                                    - Forces a full garbage collection
  force max gc                                - Forces a maximum compaction garbage collection
  retrieve complete gc history                - Retrieves the complete GC history of a VM into a local file

__ JIT commands: ____________________________

  compile                                     - Forces compilation of the specified method(s)
  deoptimize                                  - Deoptimizes all activations of the specified method(s)
  deoptimizeall                               - Deoptimizes all methods
  osrcompile                                  - Forces osr compilation of the specified method

__ VM commands: _____________________________

  change command line flag                    - Changes command line flags of a VM
  crash vm                                    - Crashes a VM
  exit vm                                     - Exits a VM
  mallocstat reset                            - Resets malloc statistics value
  mallocstat startcap                         - Starts malloc statistics capture
  mallocstat stopcap                          - Stops malloc statistics capture
  set core size to max                        - Set current soft limit of core size to hard limit
  set debugging port                          - Sets debugging port of a VM
  set debugging port range                    - Sets debugging port range of a VM
  set trace flags                             - Sets trace flags of a VM
  start debugging                             - Starts on-the-fly debugging
  stop command line profiling                 - Stops command line profiling of a VM
  stop debugging                              - Stops on-the-fly debugging

__ VM selection commands: ___________________

  display vms                                 - Displays the VMs in the cluster
  select vm                                   - Selects a VM (in the cluster)
  select vm all                               - Selects all VMs in the cluster

__ Jvmmon commands: _________________________

  exit                                        - Exits Jvmmon
  help                                        - Shows the help text
  history                                     - Shows a list of the commands executed
  print to console                            - Redirect print commands to console output
  print to file                               - Redirect print commands to local file
  quit                                        - Quits Jvmmon
  help "<command>"                            - Displays detailed help about the specified command
  !                                           - Repeats the last command
  !!                                          - Repeats the last command
  !N                                          - Repeats command with number N in history
  !TEXT                                       - Repeats command that started with TEXT

使用例

例えば print class statistic では以下のような情報が取得できます。jmap で取得できる情報に近いですが、よりわかりやすいです。プロンプトは入力補完も効くので長いコマンドの入力もスムーズです。

$ print class statistic
| Class statistic for young and old generation at GC Nr. 0

|       |   overall  |    overall    |        |
| Rank  |  # objects | Size in bytes |  perc. |    Class Loader Id   | Class
|----------------------------------------------------------------------------------------------------------------
|     1 |        957 |         84504 |  27.33 |                    0 | char[]
|     2 |        552 |         63080 |  20.40 |                    0 | java.lang.Class
|     3 |        671 |         39664 |  12.83 |                    0 | java.lang.Object[]
...省略

ポイントとしては、上記のコマンド実行に連動して、VM側でプロファイルモードが、

  • プロファイルモードOn
  • プロファイリング
  • プロファイルモードOff

とオンラインで切り替わることです。

通常、Java VMの内部情報を取得するにはパフォーマンスの劣化に注意を払って行うのですが、この機能のおかげでCPUやメモリの劣化を最小限に抑えながらプロファイリングが行えるとのことです。

また、自分の場合はJVMのパフォーマンスチューニングにはCUIのツールをメインに使いますが、それでもjconsoleやjmcはグラフィカルに大枠掴んだり、CUIでは覚えきれない細かい情報も、クリック一つで見られて便利です。jvmmonにもGUIツールが付属しています。以下のコマンドで起動できます。

./sapjvm_8/bin/jvmmon-gui

以下のような画面が表示されます。ここからもjvmmonの機能を使ってVMの各種情報を取得することができます。

GUIが入ってないサーバの場合はjvmmondというデーモンを立ち上げることで、外部から jvmmon 接続できます。

  • サーバー側
./sapjvm_8/bin/jvmmond -port 8888
  • クライアント側
./sapjvm_8/bin/jvmmon -h server_hostname -p 8888

jvmmon はかなり便利。Oracle JDKで動いているプログラムで原因不明の問題起こった時にも、SAPJVMでコンパイル動かしてみて再現できるならそこで原因を見つけるなんていうのも、方法としてはありえるかもしれないです。

(補足) SapMachine

Oracle JDKの話を比較対象としてきましたが、SAP MachineというOpen JDKをSAPがForkしたものも存在しています。

Java SEがリリース8から11にかけて大きく変化したのはニュースにもなっていたので有名だと思いますが、

SAP JVMはJava SE 1.4の時はSun Microsystemsのライセンス、今はOracleのライセンスに基づいて提供されています。OSSではないのでソースコードは提供されてないです。Java SE 8までを利用したい場合はこちらになりそうです。

逆にSAP MachineはOpenJDKなのでソースコードも提供されてます。(Githubに上がってますし)Java SE 11以降のバージョンに対応するのは、現時点ではこちらのとなっているようです。

github.com

This project contains a downstream version of the OpenJDK project. It is used to build and maintain a SAP supported version of OpenJDK for SAP customers who wish to use OpenJDK in their production environments.

この辺りの話は、こちらのスライドを読ませていただくと流れが理解できます。

www.slideshare.net