JavaのStackOverflowErrorとOutOfMemoryErrorの違いとは?JVMのメモリ構造をわかりやすく解説
Javaプログラムを実行すると、OSはJVMに対して一定量のメモリを割り当てます。JVMはこのメモリを「スタック領域」と「ヒープ領域」の2つに分割して管理しています。スタックはメソッドの実行に使用され、ヒープはオブジェクトの格納に使用されます。そして、スタックが満杯になると java.lang.StackOverflowError がスローされ、ヒープが満杯になると java.lang.OutOfMemoryError がスローされます。それぞれの仕組みと発生原因を詳しく見ていきましょう。
StackOverflowError(スタックオーバーフローエラー)とは
- スタックはメソッドの実行に使用されます。メソッドが呼び出されるたびに、スタックメモリ内に1つのブロック(スタックフレーム)が作成されます。
- このブロックには、引数・ローカル変数・オブジェクトへの参照など、そのメソッドに関連するデータが格納されます。
- メソッドの実行が完了すると、格納されていたデータとともに、このブロックはスタックから取り除かれます。
- すべてのメソッド呼び出しは、必ず実行を終えてスタックメモリから退出しなければなりません。
- 何らかの理由でメソッドがスタック上に残り続けると、スタックが満杯になり、JVMは
java.lang.StackOverflowErrorをスローします。典型的な原因は、終了条件のない無限再帰呼び出しです。
OutOfMemoryError(メモリ不足エラー)とは
- Javaで生成されたオブジェクトは、すべてヒープメモリに格納されます。不要になったオブジェクトは、メモリから解放される必要があります。
- ガベージコレクタ(GC)が、ヒープメモリから不要なオブジェクトを自動的に除去します。
- ただし、有効な参照が残っているオブジェクトはGCによって回収されません。回収対象になるのは、どこからも参照されていないオブジェクトだけです。
- 意図せず参照を保持し続けると(いわゆるメモリリーク)、不要なはずのオブジェクトが回収されず、ヒープを圧迫していきます。
- 新しいオブジェクトを格納するための空き領域がヒープメモリに残っていない場合、JVMは
java.lang.OutOfMemoryErrorをスローします。
両者の違いのまとめ
StackOverflowErrorは「メソッドの実行管理に使うスタック領域」が枯渇したときに発生し、OutOfMemoryErrorは「オブジェクトを格納するヒープ領域」が枯渇したときに発生します。前者は主に深すぎる再帰呼び出しが原因で、後者はメモリリークや過大なオブジェクト生成が原因となることが多いです。エラーの種類を見分けることで、ボトルネックがスタック側なのかヒープ側なのかを素早く特定でき、適切な対策(再帰の見直し、ヒープサイズの調整、参照の解放など)につなげられます。
-
JavaのJFrameとJDialogの違いとは?特徴と使い分けを解説
JavaのSwingには、ウィンドウを表示するためのトップレベルコンテナとしてJFrameとJDialogが用意されています。どちらもよく似た役割を持ちますが、動作や用途には重要な違いがあります。この記事では、それぞれの特徴をサンプルコードとともに解説し、最後に使い分けのポイントをまとめます。 JFrameとは フレームに追加されたコンポーネントは「コンテンツ」として扱われ、contentPaneによって管理されます。JFrameにコンポーネントを追加する際は、フレーム本体ではなくcontentPaneに対して追加する必要があります。 JFrameは、タイトル、境界線、(オプションで)メニュ
-
JavaのGridLayoutとGridBagLayoutの違いを徹底解説!特徴と使い分けのポイント
JavaのAWT/Swingには複数のレイアウトマネージャーが用意されていますが、その中でもGridLayoutとGridBagLayoutは、コンポーネントを格子状(グリッド)に配置するという点でよく似ています。しかし、両者には重要な違いがあります。 GridLayoutは、すべてのコンポーネントを矩形のグリッド内に配置し、領域を同じサイズの長方形に分割して、各コンポーネントをそれぞれのセルの中に収めます。一方、GridBagLayoutは柔軟性の高いレイアウトマネージャーであり、コンポーネントのサイズを揃えることなく、縦方向・横方向に整列させて配置できます。各GridBagLayoutオブ