プロジェクト

全般

プロフィール

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では、サーバーコンパイラが使われる環境では階層的コンパイルがデフォルトとなります。

Tiered compilation(階層コンパイラ)

-XX:+TieredCompilation 指定時(64bit JVMではデフォルトで指定)

  • インタプリター、C1、およびC2の混成
  • レベル0~4
Level JITコンパイラ
0 インタプリタ
1 C1 ただしプロファイリングなし
2 C1 ただし基本的なプロファイリング使用
3 C1 ただしすべてのプロファイリング使用
4 C2
  • 2000回実行されたコードは、インタプリタからC1へ移行(状況に応じ、レベル0からレベル1~3のいずれかに遷移)
  • 15000回実行されたコードは、C1からC2へ移行
  • -XX:TieredStopAtLevel=N で、階層コンパイルの上限を指定可能
    • 1を指定すると、Level 2以降には遷移しないようです。ただし、Level0→2, 0→3への遷移に該当する場合どうなるかは未調査(インタプリタにとどまるのか、Level 1に遷移するのか?)
    • 2を指定すると、Level 1またはLevel 2

一般的には、レベル0→レベル3→レベル4と遷移

参考

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

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]が適用)

JDK 8u131 32bit Windows版のデフォルトヒープサイズを表示

サーバーJVM(32bit)

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

JDK 8u131 32bit Windows版のデフォルトヒープサイズを表示

JDK 9 EA b167 32bit Windows版のデフォルトヒープサイズを表示

サーバーJVM(64bit)

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

JDK 8u131 64bit Windows版のデフォルトヒープサイズを表示

JDK 9 EA b167 64bit Windows版のデフォルトヒープサイズを表示

メタスペース

項目 JDK 8 32bit JDK8 64bit
初期サイズ 12MB 21MB @-XX:MetaspaceSize

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

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

推奨オプション

参考資料

書籍


ほぼ7年前に更新