LoginSignup
12
15

More than 3 years have passed since last update.

Java起動オプション標準化

Posted at

この記事について

長年、Javaを使ったIT開発の仕事をしていますが、Javaの起動オプション決定は毎回試行錯誤している気がします。
GCの特性毎にHeap,Metaspace,New領域(Eden/Survivor),Old領域などの複雑なメモリ管理を調べつつ、-Xオプションを設定してみる
この作業、10年前から変わってない気がします。
細かいJavaのメモリ管理については別の記事に譲るとして、ここでは完結に
ここだけいじればオーケー
的な情報を示したいと思います。
ご意見などあれば、是非コメントお願いします。

前提

ここでは、常駐して利用されるJavaVM(OpenJDK 8u20以降のHotspot JavaVM)の起動オプションを想定しています。
常駐とは・・・

  • アプリケーションを起動したら、停止命令を送るまで起動したままの物
  • 代表例はTomcatやJetty,WildFlyなどのアプリケーションサーバ
  • Spring-bootを使ったアプリケーション
  • もちろん自作のJavaSEアプリケーションでも常駐するものならOK 

対象外を言えばよかったかも

  • 一回実行して、処理が終了したらJavaVMも終了するものは対象外

商用環境JavaVM 推奨起動オプション

ここでは起動オプション(例)を先に示し、それぞれの項目の意味と設定内容を説明します。
この設定をベースにヒープサイズファイル出力先ぐらいを変更(チューニング?)すればよいでしょう。

起動オプション決定方針

JavaVM起動オプション様々な設定が存在しますが、可能な限りエルゴノミクス・デフォルト(※)を利用し、最低限の設定を行うものとします。
エルゴノミクス・デフォルト:JavaVMが利用環境(CPUコア数やOS、物理メモリ量などの情報)から最適な値を自動設定します。要するに、できる限りJavaVMにおまかせすると言うことです。

JavaVMオプション(例)

> java -Xms8192M
       -Xmx8192M
       -XX:+CrashOnOutOfMemoryError
       -XX:+HeapDumpOnOutOfMemoryError
       -XX:HeapDumpPath=/AAA/BBB/CCC/hprof-dumps
       -Xlog:gc:file=/AAA/BBB/CCC/gclogs/gc_%p_%t.log:time:filecount=10:size=100M
    (以降、メインクラス名 アプリケーション固有の起動引数)

起動オプションの内容

  • GCアルゴリズム=G1GCを使用(デフォルト)
    • 最大停止時間目標 200ms(デフォルト)
    • metaspace,SurvivorRatio/NewRatioなどは、JavaVMにおまかせ
  • ヒープサイズ8192Mバイト 最大=最小
  • OutOfMemoryErrorが発生した時はプロセスを停止し、クラッシュレポートを出力
  • OutOfMemoryErrorが発生した時に、ヒープダンプを出力
  • ヒープダンプの出力先:/AAA/BBB/CCC/hprof-dumps
  • gcログ関連
    • gcログファイルは /AAA/BBB/CCC/gclogs/に格納する
    • ファイル名はgc_[プロセスID]_[時間].log
    • 1ファイルのサイズ=100Mバイト
    • ファイル世代数=10 でローテーション
    • gcログに各行にタイムスタンプを出力する

JavaVMオプションまとめ

よく使うJavaVM起動オプションの説明と、設定値の決め方を以下にまとめます。

起動オプション(-Xlog:gc以外)

起動オプション 設定値 設定値の例 説明(決め方)
-Xms ヒープサイズ最小 8192M 初期のヒープサイズ
物理メモリの量からOSが利用するメモリ量を引いた値を設定 -Xmxと同じ値にする
-Xmx ヒープサイズ最大 8192M 最大ヒープサイズ
物理メモリの量からOSが利用するメモリ量を引いた値を設定 -Xmsと同じ値にする
-XX:MaxGCPauseMillis 停止してもよい時間(ミリ秒) 200 GCによる最大停止時間の目標。省略時は200ms。GCが頻発する場合は増やしてみる。
-XX:+CrashOnOutOfMemoryError - - OutOfMemory発生時にプロセスを終了し、クラッシュレポートを出力する。これはいつも設定すべき
-XX:+HeapDumpOnOutOfMemoryError - - OutOfMemory発生時にヒープダンプを出力する。ヒープが大きい場合は、ヒープダンプファイルも大きくなるため、出力先に注意する。見るつもりがないなら出力しない
-XX:HeapDumpPath= ヒープダンプの出力先 /.../hprof-dumps 上記ヒープダンプの出力先
-Dcom.sun.management.jmxremote= JMXリモート接続の許可 true 監視ツールなどからJMXリモート接続する場合に設定
-Dcom.sun.management.jmxremote.port= 上記接続ポート 7091 上記接続時のポート番号
-Dcom.sun.management.jmxremote.authenticate= 上記接続時に認証するか false 上記接続時に認証するか
-Dcom.sun.management.jmxremote.ssl= 上記接続時にSSL通信するか false 上記接続時にSSL通信するか

起動オプション(-Xlog:gc)詳細にgcログを出力したい場合は -Xlog:gc*

-Xlog:gc:[ファイル名]:[修飾]:filecount=[世代数]:size=[ファイルサイズ]

設定項目 設定例 説明(決め方)
[ファイル名] /gclogs/gc_%p_%t.log /gclogsディレクトリに格納
%p=プロセスID,%t=タイムスタンプでファイル名を付ける
 コンテナ環境で実行する場合は、"stdout" と記載することにより、標準出力を利用することができる
[修飾] time,tags time=gcログにタイムスタンプを出力
tags=ログにタグを設定 これはコンテナ環境などで標準出力を利用する際に便利
[世代数] 10 ファイルの世代数
[ファイルサイズ] 100M 1ファイルのサイズ

終わりに

この記事にある設定値だけであれば楽に理解できると思います。このほかに監視エージェントへの接続設定があるかもしれませんが、それ以外の難しい設定を、意味が分からず呪い(まじない)のように使うのだけは止めましょう。状況を悪化させるだけでなので、おとなしくアプリケーションの実装を見直すべきだと思います。(長い経験から)

12
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
15