IBM Semeru Runtimes や IBM Javaのダンプエージェントによるdump出力設定を知る

# 概要
IBM Semeru RuntimesやIBM JavaのOpenJ9 Java仮想マシン（JVM）のダンプ・エージェントによるdump出力設定を知ることで、様々なタイミングでダンプファイルや診断情報を生成することが可能になります。

# はじめに
IBM Semeru RuntimesやIBM JavaのOpenJ9系JVMにおいて一般的な保護フォールトのようなさまざまなイベントが発生すると、分析のためにさまざまなタイプの診断情報が生成されます。
生成されるダンプは、IBM Semeru RuntimesやIBM JavaのOpenJ9系JVMの起動時に初期化されるダンプ・エージェントによって制御されます。
ほとんどの場合、ダンプ・エージェントのデフォルト設定で十分ですが、JVM引数で`-Xdump`を変更することで、様々なJVMイベント用のダンプ・エージェントを追加・削除したり、デフォルトのダンプ設定を更新し、生成されるダンプの出力タイミング、個数や出力ディレクトリーなどを制御することができるようになります。

# デフォルトの-Xdump設定について
まず、最初にデフォルトで有効となっている-Xdumpオプション設定について紹介します。
有効なXdump設定は、"-Xdump:what"で確認することが可能で、デフォルトの-Xdump設定は、以下になります。

【デフォルト-Xdump設定】
```
> java -Xdump:what

Registered dump agents
----------------------
-Xdump:system:
    events=gpf+abort+traceassert+corruptcache,
    file=/home/user/core.%Y%m%d.%H%M%S.%pid.%seq.dmp,
    range=1..0,
    priority=999,
    request=serial
----------------------
-Xdump:system:
    events=systhrow,
    filter=java/lang/OutOfMemoryError,
    file=/home/user/core.%Y%m%d.%H%M%S.%pid.%seq.dmp,
    range=1..1,
    priority=999,
    request=exclusive+compact+prepwalk
----------------------
-Xdump:heap:
    events=systhrow,
    filter=java/lang/OutOfMemoryError,
    file=/home/user/heapdump.%Y%m%d.%H%M%S.%pid.%seq.phd,
    range=1..4,
    priority=500,
    request=exclusive+compact+prepwalk,
    opts=PHD
----------------------
-Xdump:java:
    events=gpf+user+abort+traceassert+corruptcache,
    file=/home/user/javacore.%Y%m%d.%H%M%S.%pid.%seq.txt,
    range=1..0,
    priority=400,
    request=exclusive+preempt
----------------------
-Xdump:java:
    events=systhrow,
    filter=java/lang/OutOfMemoryError,
    file=/home/user/javacore.%Y%m%d.%H%M%S.%pid.%seq.txt,
    range=1..4,
    priority=400,
    request=exclusive+preempt
----------------------
-Xdump:snap:
    events=gpf+abort+traceassert+corruptcache,
    file=/home/user/Snap.%Y%m%d.%H%M%S.%pid.%seq.trc,
    range=1..0,
    priority=300,
    request=serial
----------------------
-Xdump:snap:
    events=systhrow,
    filter=java/lang/OutOfMemoryError,
    file=/home/user/Snap.%Y%m%d.%H%M%S.%pid.%seq.trc,
    range=1..4,
    priority=300,
    request=serial
----------------------
-Xdump:jit:
    events=gpf+abort,
    file=/home/user/jitdump.%Y%m%d.%H%M%S.%pid.%seq.dmp,
    range=1..0,
    priority=200,
    request=serial
----------------------
```

    
基本的な設定の構成は以下のような構成になっています。
```
-Xdump:<Dump agents>:<Dump events>:<Dump Options>
```

デフォルトの-Xdump設定内容の概要は以下になります。
```
<Dump agents>
-Xdump:system : core dump 出力に関する設定
-Xdump:heap   : heapdump 出力に関する設定
-Xdump:java   : javacore　出力に関する設定

<Dump events>
events= ***   : JVMの稼働中にトリガーされる発生イベント設定

<Dump Options>
filter= ***   : トリガーされるイベントによっては、filter設定が可能
range= ***    : イベントの特定の発生時にrange設定によりダンプ・エージェントを起動したり停止したりすることができます。（range=1..4:1回目から４回目までで有効。５回目以降はエージェントは反応しません。（range=1..0 :　常にエージェントが反応します））
priority= *** : 同じイベントに対して-Xdump設定が実行される優先順位の設定
request= ***  :ダンプ・エージェントを起動する前に、JVMに状態を準備するよう求める設定
```

各設定項目の詳細については、[IBM SDK, Java Technology Edition:-Xdump](https://www.ibm.com/docs/ja/sdk-java-technology/8?topic=options-xdump)をご確認ください。


デフォルト設定の`-Xdump:system`に関する設定項目の概要は以下のようになります。
```
-Xdump:system:events=gpf+abort+traceassert+corruptcache,file=/home/user/core.%Y%m%d.%H%M%S.%pid.%seq.dmp,range=1..0,priority=999,request=serial
```
-Xdump:systemのeventオプション`events=gpf,abort,traceassert,corruptcache`が発生した場合に、ダンプファイル`/home/user/core.%Y%m%d.%H%M%S.%pid.%seq.dmp`が出力されます。
また、JVM起動から停止までの間に該当イベントが発生した場合、無制限（range=1..0）に出力されます。priorityは、同発生イベントに対して各エージェントの実行順を定義し、`priority=999`は、最優先で実行されます。
`request=serial`は、このダンプが終了するまで、他の-Xdump処理を一時停止するオプションとなります。

```
-Xdump:system:events=systhrow,filter=java/lang/OutOfMemoryError,file=/home/user/core.%Y%m%d.%H%M%S.%pid.%seq.dmp,range=1..1,priority=999,request=exclusive+compact+prepwalk
```
また、-Xdump:systemオプション`events=systhrow,filter=java/lang/OutOfMemoryError`は、java/lang/OutOfMemoryErrorがスローされた（発生した）場合に、`/home/user/core.%Y%m%d.%H%M%S.%pid.%seq.dmp`が出力されます。
また、JVM起動から停止までの間に該当イベントが発生した場合、１回だけ（range=1..1）出力されます。priorityは、同発生イベントに対して各エージェントの実行順を定義し、`priority=999`は、最優先で実行されます。
`request=exclusive+compact+prepwalk`が、設定されているので、dump出力前に、fullgcが実行され、heapを精査します。



# -Xdump設定を変更する
-Xdump設定を変更する場合、デフォルトの-Xdump設定を一旦無効にした上で、新たに-Xdump設定を追記するか、デフォルト-Xdump設定を上書きする形で新たな-Xdump設定を設定します。

例) `-Xdump:system:none`により、一旦-Xdump:systemに対する設定を無効にした上で、-Xdump:systemを新たに設定します。デフォルト-Xdump設定から、`-Xdump:system:events=systhrow,filter=java/lang/OutOfMemoryError`が削除され、java/lang/OutOfMemoryError発生時にcore dumpが出力しないようにする設定となります。
```
> java -Xdump:system:none -Xdump:system:events=gpf+abort+traceassert+corruptcache,file=/home/user/core.%Y%m%d.%H%M%S.%pid.%seq.dmp,range=1..0,priority=999,request=serial -Xdump:what

-Xdump:system:
    events=gpf+abort+traceassert+corruptcache,
    file=/home/user/core.%Y%m%d.%H%M%S.%pid.%seq.dmp,
    range=1..0,
    priority=999,
    request=serial
----------------------
-Xdump:heap:
    events=systhrow,
    filter=java/lang/OutOfMemoryError,
....
```

【参考情報】
WASやLiberty環境における-Xdump設定は、JVM引数に設定します。

[WebSphere Application Server : Java 仮想マシン設定](https://www.ibm.com/docs/ja/was/9.0.5?topic=jvm-java-virtual-machine-settings)

[WebSphere Application Server Liberty のチューニング](https://www.ibm.com/docs/ja/was-liberty/nd?topic=tuning-liberty)

[Setting generic JVM arguments in WebSphere Application Server](https://www.ibm.com/support/pages/node/397841)

---
以下、様々な状況におけるdumpファイルを取得するための-Xdump設定例を示します。

# 手動でcore dump/heapdumpを出力させる設定
Unix環境においては、`-Xdump:***:events=user`の設定により"kill -3 [PID]"をトリガーとしてdump出力をコントロールできます。
これを利用し、"kill -3 [PID]"実行タイミングで、core dump/heapdumpを手動できます。
```
>java -Xdump:system+heap:events=user -Xdump:what

-Xdump:system:
    events=gpf+user+abort+traceassert+corruptcache,
    file=/home/user/core.%Y%m%d.%H%M%S.%pid.%seq.dmp,
    range=1..0,
    priority=999,
    request=serial
----------------------
...

----------------------
-Xdump:heap:
    events=user,
    file=/dump/heapdump\heapdump.%Y%m%d.%H%M%S.%pid.%seq.phd,
    range=1..0,
    priority=500,
    request=exclusive+compact+prepwalk,
    opts=PHD
....
```

※heapdump取得前にfullgcを実行させたくない場合には、requestオプションから"compact"を抜いて設定します。
```
-Xdump:heap:events=user,request=exclusive+prepwalk
```

# JVM起動時、または、停止時にdumpを出力させる設定
enventsの"vmstart"または、"vmstop"を使用します。
予期せぬJVMの停止処理が実行された場合に、停止処理実行スレッド処理を確認する際に有効です。
- 例）JVM停止時に、javacore/heapdumpを出力させる設定:
```
-Xdump:heap+java:events=vmstop
```
# 特定のException で dumpさせる設定
filterオプションを使用することで、特定のExceptionをトリガーとし、dumpを出力させることが可能です。
特に、意図しないタイミングで予期しないExceptionが発生する場合、JIT関連の問題が疑われます。JIT関連の問題の調査にはcore dumpが必要になるためException発生をトリガーにしcore dumpを取得する場合に有効です。

- 例)"com/ibm/MyApplication.myMethod（）"にて"java/lang/NullPointerException"がスローされたタイミングでcore dump/javacoreを出力させる設定
```
-Xdump:system+java:events=throw+systhrow,,filter=java/lang/NullPointerException#com/ibm/MyApplication.myMethod,request=exclusive+prepwalk
```

- 例)"com/ibm/MyApplication.main（）"から呼び出されたメソッドで"java/lang/NullPointerException"がスローされたタイミングでcore dumpを出力させる設定
Exceptionが汎用クラスまたはユーティリティ・クラスでスローされている事象においてスタック・フレーム・オフセットを使用すると、スローするメソッドを呼び出すメソッド名でフィルタリングできます。
```	
-Xdump:system+java:events=throw+systhrow,filter=java/lang/NullPointerException#com/ibm/MyApplication.main#1,request=exclusive+prepwalk
```


# objectのallocationサイズでjacvacore出力させる設定
`events=allocation`は、大きなアロケーション要求を行うような処理スレッドののスタック・トレースを確認する場合に役立ちます。

- 例)100mbより大きなアロケーション要求があった場合に、スレッドのスタック情報を出力します。
```
-Xdump:stack:events=allocation,filter=#100m
```

- 例)意図しないfullgc(global gc)が発生している場合に、`events=fullgc`を使うことでfullgc(global gc)をトリガーとしてjavacorを出力させる設定が可能です。
```
-Xdump:java:events=fullgc
```

# OutOfMemoryError発生時にJVMを停止させる設定
通常、OutOfMemoryError発生によりJVMは停止しませんが、OutOfMemoryErrorが発生しているJVMの状態は不安定な状態となる可能性があるため、以下の-Xdump設定によりOutOfMemoryError発生に伴いJVMを停止することが可能です。

OutOfMemoryError発生時に、execオプションで指定したコマンドを実行します。
- 例) OutOfMemoryError発生時に、"kill -9"("taskkill")コマンドを実行する設定
```
-Xdump:tool:events=systhrow,filter=java/lang/OutOfMemoryError,exec="kill -9 %pid"
* Windows環境：-Xdump:tool:events=systhrow,filter=java/lang/OutOfMemoryError,exec="taskkill /F /PID %pid"
```

この設定の応用として以下のような設定も可能です。

OutOfMemoryError発生時に、dump出力を待たず早急にJVMを停止する。
- 例) `priority=999`をつけることでOutOfMemoryError発生時に、他の-Xdumpオプションよりも"kill -9"("taskkill")コマンドを実行を優先する設定
```
-Xdump:tool:events=systhrow,filter=java/lang/OutOfMemoryError,exec="kill -9 %pid",priority=999
* Windows環境：-Xdump:tool:events=systhrow,filter=java/lang/OutOfMemoryError,exec="taskkill /F /PID %pid",priority=999
```

また、連続してOutOfMemoryErrorが発生した場合、割り当てられているCPUリソースの状況によっては-Xdump処理が並列して実行される場合があり、そのような環境では-Xdumpによるdump出力処理を待たず、`exec="kill -9 %pid"`が実行されてしまう場合があります。
そのような状況への対応として、optオプションにより`exec="kill -9 %pid"`実行タイミングをコントロールすることが可能です。
- 例) `"opts=ASYNC+WAIT10000"`をつけることで、OutOfMemoryError発生から60秒後(60000ms後)に"kill -9"("taskkill")コマンドを実行する設定
```
-Xdump:tool:events=systhrow,filter=java/lang/OutOfMemoryError,exec="kill -9 %pid",opts=ASYNC+WAIT60000
* Windows環境：-Xdump:tool:events=systhrow,filter=java/lang/OutOfMemoryError,exec="taskkill /F /PID %pid",opts=ASYNC+WAIT60000
```

# dump出力ディレクトリー、ファイル名を変更する設定

**A. dumpファイルの出力ディレクトリー変更**
dump出力ディレクトリーを変更する方法として以下の２つがあります。

**a. -Xdump:directoryでdump出力先を一括で変更する**
`directory=<path>`を使用し出力ディレクトリーを指定することで、-Xdumpによって出力されるdumpファイルが指定したディレクトリー配下に出力されます。
```
-Xdump:directory=<path>　
```

```
>java -Xdump:directory=/dump -Xdump:what

Registered dump agents
----------------------
-Xdump:system:
    events=gpf+abort+traceassert+corruptcache,
    file=/dump/core.%Y%m%d.%H%M%S.%pid.%seq.dmp,  <<<
    range=1..0,
    priority=999,
    request=serial
-----------------------
....
```

**b. 各エージェント設定で個別に出力ファイルを変更し、個別に出力先を変更する**
fileオプションで出力dumpファイルをフルパスで指定します。
```
> java -Xdump:system:file=/dump/core.%Y%m%d.%H%M%S.%pid.%seq.dmp -Xdump:heap:file=/dump/heapdump/heapdump.%Y%m%d.%H%M%S.%pid.%seq.phd -Xdump:what

Registered dump agents
----------------------
-Xdump:system:
    events=gpf+abort+traceassert+corruptcache,
    file=/dump/core/core.%Y%m%d.%H%M%S.%pid.%seq.dmp,   <<<
    range=1..0,
    priority=999,
    request=serial
----------------------
-Xdump:system:
    events=systhrow,
    filter=java/lang/OutOfMemoryError,
    file=/dump/core/core.%Y%m%d.%H%M%S.%pid.%seq.dmp,   <<<
    range=1..1,
    priority=999,
    request=exclusive+compact+prepwalk
----------------------
-Xdump:heap:
    events=systhrow,
    filter=java/lang/OutOfMemoryError,
    file=/dump/heapdump/heapdump.%Y%m%d.%H%M%S.%pid.%seq.phd,   <<<
    range=1..4,
    priority=500,
    request=exclusive+compact+prepwalk,
    opts=PHD
----------------------
```

**B. 出力dumpファイル名を変更**
出力dumpファイル名は、-Xdump設定のfileオプションで変更可能です。
```
file=/home/user/core.%Y%m%d.%H%M%S.%pid.%seq.dmp
```

dumpファイル名に指定できるトークンは、以下で確認可能です。
```
>java -Xdump:tokens

Label tokens:

  %Y     year    1900..????
  %y     century   00..99
  %m     month  01..12
  %d     day    01..31
  %H     hour   00..23
  %M     minute 00..59
  %S     second 00..59

  %pid   process id
  %uid   user name
  %seq   dump counter
  %tick  msec counter
  %home  java home
  %last  last dump
  %event dump event
```

# まとめ
-Xdumpオプション設定を使いこなすことで様々な事象において調査に有益なdumpファイルを出力することができるようになります。上記でご紹介した設定の以外にも様々なオプション設定があります。
-Xdump設定を選定するにあたり[OpenJ9: Xdump Option Builder](https://eclipse.dev/openj9/tools/xdump_option_builder.html)を使用すると-Xdumpの非互換性を回避し、正しいオプションを指定することに役立ちます。
ぜひ、ご利用いただき発生事象に合致したタイミングでのdump取得にお役立てください。