Javaアプリケーションを動かしていると「OutOfMemoryError」に遭遇したり、「ヒープサイズを調整してください」というアドバイスを目にしたりすることはないでしょうか。
「ヒープサイズって何?どうやって設定するの?」という疑問をお持ちの方も多いと思います。
この記事では、ヒープサイズとは何か、最大・初期ヒープサイズの設定方法とパフォーマンスチューニングについて詳しく解説しています。
Javaアプリケーションのパフォーマンスを改善したい方はぜひ参考にしてください。
ヒープサイズとは?Javaにおける基本的な意味
それではまず、ヒープサイズの基本的な意味について解説していきます。
ヒープサイズとは、Javaアプリケーションがオブジェクトを格納するために使えるヒープ領域のメモリ容量のことです。
JVM(Java仮想マシン)はアプリケーション起動時に一定のヒープ領域を確保し、オブジェクトの生成に応じてヒープを使用します。
ヒープが足りなくなるとGC(ガベージコレクション)が頻繁に走り、最終的にはOutOfMemoryErrorが発生します。
初期ヒープサイズと最大ヒープサイズの違い
| 設定項目 | JVMオプション | 意味 |
|---|---|---|
| 初期ヒープサイズ | -Xms | JVM起動時に確保するヒープの初期サイズ |
| 最大ヒープサイズ | -Xmx | ヒープが拡張できる上限サイズ |
| Young世代サイズ | -Xmn | 新しいオブジェクトを格納する若い世代のサイズ |
| スタックサイズ | -Xss | スレッドごとのスタックサイズ |
ヒープサイズのデフォルト値
JVMのヒープサイズのデフォルト値は、JVMのバージョンやシステムの物理メモリによって異なります。
Java 8以降では、物理メモリの1/4を最大ヒープサイズ(-Xmx)、1/64を初期ヒープサイズ(-Xms)とするのがデフォルト設定の傾向です。
デフォルト値ではアプリケーションの要件に合わない場合が多いため、本番環境では適切なヒープサイズを明示的に設定することが推奨されます。
ヒープサイズの設定方法と具体的なコマンド例
続いては、ヒープサイズの設定方法と具体的なコマンド例を確認していきます。
JVMオプションでヒープサイズを指定する方法
ヒープサイズを指定してJavaプログラムを起動する例:
java -Xms256m -Xmx1024m -jar myapp.jar
(初期ヒープ256MB、最大ヒープ1GBで起動)
Spring Bootアプリの例:
java -Xms512m -Xmx2g -jar spring-app.jar
(初期512MB、最大2GB)
単位は「m」(メガバイト)または「g」(ギガバイト)で指定します。
初期サイズと最大サイズを同じ値に設定するメリット
-Xmsと-Xmxを同じ値に設定すると、JVMの起動時からフルサイズのヒープを確保するため、実行中のヒープ拡張処理が発生せずパフォーマンスが安定します。
本番環境やパフォーマンスが重要なシステムでは、初期サイズと最大サイズを同じ値にすることが推奨されることが多いです。
ヒープサイズのチューニングとパフォーマンス最適化
続いては、ヒープサイズのチューニングとパフォーマンス最適化を確認していきます。
GC(ガベージコレクション)の頻度とヒープサイズの関係
ヒープサイズが小さすぎるとGCが頻繁に発生し、アプリケーションの処理が止まるGCポーズが多くなってパフォーマンスが低下します。
逆にヒープサイズが大きすぎると、GCが走ったときの1回あたりのポーズ時間が長くなる問題があります。
アプリケーションの特性に合わせてバランスの取れたサイズを設定することが重要です。
ヒープ使用量の監視ツール
適切なヒープサイズを決めるためには、実際のヒープ使用量を監視することが重要です。
JDKに付属する「jvisualvm」や「jconsole」、商用ツールの「JProfiler」「YourKit」などのツールでリアルタイムのヒープ使用量やGCの動作を監視できます。
GCログを有効にして分析することで、どのタイミングでGCが多発しているかを特定し、最適なヒープサイズを導き出せます。
コンテナ環境でのヒープサイズ設定の注意点
DockerなどのコンテナでJavaアプリを動かす場合、JVMがコンテナのメモリ制限ではなくホストOSの物理メモリを参照してヒープサイズを設定してしまうことがあります。
Java 10以降では「-XX:+UseContainerSupport」オプションが有効になっており、コンテナのメモリ制限を正しく認識できるようになっています。
コンテナ環境では「-XX:MaxRAMPercentage」オプションでコンテナメモリのパーセンテージでヒープを設定する方法が現代的なアプローチでしょう。
まとめ
この記事では、ヒープサイズとは何か、初期・最大ヒープサイズの設定方法からパフォーマンスチューニングまで詳しく解説しました。
適切なヒープサイズの設定はJavaアプリケーションのパフォーマンスと安定性に直結する重要な設定です。
監視ツールでヒープ使用量を把握しながら、-Xmsと-Xmxを最適な値にチューニングすることで、GCの影響を最小化できるでしょう。
今回の内容を参考に、Javaアプリケーションのヒープサイズを適切に管理していきましょう。