プロジェクト

全般

プロフィール

Oracle JDK8 JavaVMオプション

オプションに関するメモ

JITコンパイルに関するオプション

JITコンパイラの指定

HotSpot VMのJITコンパイラには次の2種類があります。

  • クライアントコンパイラ(C1)
  • サーバーコンパイラ(C2)

JITコンパイラの指定については、次のオプションがあります。

オプション指定 使用するJITコンパイラ デフォルトで適用される環境
-client C1 Windows 32bit版JavaVM
Linux 32bit版JavaVMでCPU(コア)が1つ
-server C1およびC2(階層的コンパイル) Windows 64bit版JavaVM
Linux 32bit版JavaVMでCPU(コア)が2つ以上
Linux 64bit版JavaVM
-server -XX:-TieredCompilation C2 なし

Oracle Java SE 8では、サーバーコンパイラが使われる環境では階層的コンパイルがデフォルトとなります。

コードキャッシュサイズの指定

JITコンパイラがコンパイルしたCPUネイティブの命令コードを格納するコードキャッシュ領域のサイズを指定するオプションです。これはネイティブメモリの領域に置かれます。

コードキャッシュ領域は、初期サイズと最大サイズがあり、最初は初期サイズだけ確保(Commit)され、いっぱいになるたびに最大サイズまで拡張されます。最大サイズを指定した分だけ最初に領域が予約(Reserve)されます。

初期サイズと最大サイズのIntelプロセッサにおけるデフォルトのサイズは次のとおりです。

JavaVMの種類 初期サイズ 最大サイズ 備考
32bit版JavaVM、C1 160KB 32MB
32bit版JavaVM、C2(階層的コンパイルを含む) 2496KB 240MB
64bit版JavaVM 2496KB 240MB

初期サイズを指定するオプションは次です。

-XX:InitialCodeCacheSize=N

最大サイズを指定するオプションは次です。

-XX:ReservedCodeCacheSize=N

サイズの算出について

  • コードキャッシュが不足したらJavaVM警告メッセージ「Code cache is full. Compiler has been disabled.」が出る
  • JConsoleを接続し、[メモリー]タブの[メモリー・プール"Code Cache"]を指定すると使用済みのサイズが確認できる

コンパイル実施の閾値

JITコンパイラがコンパイルをするのは対象コード(メソッドおよびループ)が閾値を超える数だけ繰り返し実行された場合です。
この閾値は、ベンチマークやチューニングにおける知識として知っておくべきもので、むやみに変更するべきではないとされています。

  • メソッドの繰り返し実行閾値を指定するオプション: -XX:CompileThreshold=N
    • デフォルト値: クライアントコンパイラでは1500、サーバーコンパイラでは10000
  • ループの繰り返し実行閾値を指定するオプションは、次の3つのフラグから計算式により算出
    • -XX:CompileThreshold=N
    • -XX:OnStackReplacePercentage=N(デフォルト値はクライアントコンパイラでは933、サーバーコンパイラでは140)
    • -XX:InterpreterProfilePercentage=N(デフォルト値は33)

コンパイル実施スレッド

JITコンパイラがバックグラウンドで実行するスレッドの数を指定します。

-XX:CICompilerCount=N

階層的コンパイルの場合、ここで指定した数がC1とC2に割り振られます(よって2以上の値を指定)。

デフォルトのスレッド数は次のとおりです。

  • クライアントコンパイラ 1つ
  • サーバーコンパイラ 2つ
  • 階層的コンパイル CPU数により次の表による
    CPU数 1 2 4 8 16 32 64 128
    C1 1 2 3 4
    C2 1 2 6 7 8 10

インライン化

JITコンパイラの最適化の1つインライン化を抑制できます(その必要が生じることはなさそうですが)。

-XX:-Inline

「Javaパフォーマンス」本によると、メソッドのバイトコードサイズが35バイト1以下だと無条件でインライン化対象となり、325バイト以下だとホットさに応じてインライン化されます。

1 -XX:MaxInineSize=Nでこの値を増やすことはできるが、インライン化され過ぎてデメリットを生じるので注意

エスケープ分析

JITコンパイラのサーバーコンパイラの最適化の1つエスケープ分析を抑制できます。

-XX:-DoEscapeAnalysis

コンパイルログ

  • 実行時のJavaVMオプション
    -XX:+PrintCompilation
  • jstatコマンド
    • -compilerオプションで要約情報を出力
    • -printcompilationで最後にコンパイルされたメソッド情報を出力

ガベージコレクションに関するオプション

ガベージコレクターの指定

ガベージコレクターは4種類あります。いずれも、世代別ガベージコレクターです。

ガベージコレクター名 フラグ デフォルトで適用される環境
シリアル型ガベージコレクター -XX:+UseSerialGC Windows 32bit版JavaVM
Linux 32bit版JavaVMでCPU(コア)が1つ
パラレル型ガベージコレクター -XX:+UseParallelGC -XX:+UseParallelOldGC Windows 64bit版JavaVM
Linux 32bit版JavaVMでCPU(コア)が2つ以上
Linux 64bit版JavaVM
CMSガベージコレクター -XX:+UseConcMarkSweepGC -XX:+UseParNewGC なし
G1ガベージコレクター -XX:+UseG1gc なし
  • CPU(コア)が1つしかないなら、シリアル型
  • CPU(コア)が複数あるなら、まずはパラレル型を適用し、
  • 停止時間をより短くする必要があり、CPU負荷を増やせるのであればCMSを適用し
  • CMSでは対応が難しい大きなヒープサイズを使う場合はG1GCを適用

メモリに関するオプション

スタックサイズ

スタックは、スレッドごとに領域が割り当てられます。

デフォルトのスタックサイズ

OS種類 32bit版JavaVM 64bit版JavaVM
Linux 320KB 1MB
Mac OS X N/A 1MB
Windows 320KB 1MB

一般的には、32bit版JavaVMでは128KB、64bit版JavaVMでは256KBあれば大半のアプリケーションは実行可能(「Javaパフォーマンス」より)。

スタックサイズを指定するオプション

-XssN

ヒープサイズ(デフォルト)

デフォルトのヒープサイズ(Java SE 6u18のアップデート)
http://www.oracle.com/technetwork/java/javase/6u18-142093.html

クライアントJVM

  • 初期ヒープ
    8MBまたは物理メモリの1/64(物理メモリ1GB以上のときは1GBの1/64[=16MB]で計算)
  • 最大ヒープ
    物理メモリ192MB以下のとき、物理メモリの1/2
    物理メモリ192MBより大きいとき、物理メモリの1/4(物理メモリ1GB以上のときは1GBの1/4[=256MB]で計算)

サーバーJVM(32bit)

  • 初期ヒープ
    8MBまたは物理メモリの1/64(物理メモリ1GB以上のときは1GBの1/64[=16MB]で計算)
  • 最大ヒープ
    物理メモリ192MB以下のとき、物理メモリの1/2
    物理メモリ192MBより大きいとき、物理メモリの1/4(物理メモリ 4GB 以上のときは 4GBの1/4[=1GB] で計算)

サーバーJVM(64bit)

  • 初期ヒープ
    8MBまたは物理メモリの1/64(物理メモリ1GB以上のときは1GBの1/64[=16MB]で計算)
  • 最大ヒープ
    物理メモリ192MB以下のとき、物理メモリの1/2
    物理メモリ192MBより大きいとき、物理メモリの1/4(物理メモリ 128GB 以上のときは 128GBの1/4[=32GB] で計算)

実行時の各オプションの値を調べる

java [オプション群] -XX:+PrintFlagsFinal -version

推奨オプション

参考資料

書籍

クリップボードから画像を追加 (サイズの上限: 1 GB)