JavaスタックとOOM、SOF

1816 ワード

スタックについて説明する前に、JVMのメモリ構造を簡単に説明し、仮想マシンスタック、スタック、メソッド領域、プログラムカウンタ、ローカルメソッドスタックの5つの部分に分けます.
スタック:スレッドはプライベートで、ライフサイクルとスレッドのライフサイクルは同じです. スタックはいくつかの列フレームから構成される. 各メソッドは、作成された実行時に、ローカル変数、オペランドスタック、ダイナミックリンク、メソッド戻りアドレスなどを格納するスタックフレームを作成します. 各メソッドは、呼び出しから実行完了まで対応する1つのスタックフレームの仮想マシンスタック内のインスタックおよびアウトスタック
ヒープ:スレッド共有、仮想マシン起動時に作成、オブジェクトインスタンスを格納するGC管理の主な領域
≪メソッド領域|Method Area|emdw≫:仮想マシンにロードされたクラス情報、タイプの定数プール、静的変数、フィールド、メソッド情報などを格納するスレッド共有
プログラムカウンタ:スレッドはプライベートで、現在のスレッドが実行するバイトコード行番号インジケータで、各スレッドには独立したプログラムカウンタがあり、バイトコード解釈器が動作するときにその値を変更することで、次の実行するバイトコード命令を選択します.
ローカルメソッドスタック:スレッドがプライベートで、主に仮想マシンで使用されるnativeメソッドサービスであり、仮想マシンスタックと類似しています.
スタックのそれぞれの特徴を簡単に説明します.一般的には、スタックはプログラムを実行するために使用され、スタックは主にオブジェクトを保存するために使用されます.スタックは先進的な後出特性を有するデータ構造であり、すなわち後置きの先取り出しである.スタックは、各ノードに値があるソートされたツリーデータ構造です.通常、スタックのデータ構造、すなわち二叉スタックと呼ばれる.
SOFフルネームStackOverFlowErrorとは、スタックオーバーフローを指し、上述したように、スタックが意味フレーム単位でスレッドの実行状態を保存していることがわかります.スレッドがメソッドを呼び出すと、JVMは新しいスタックフレームをこのスレッドのスタック空間に押し込み、メソッドの実行が終了するとスタックフレームはスタックを出ますが、メソッドの実行中、このスタックフレームはずっと存在します.したがって、メソッドのネストされた呼び出し階層が多すぎると、スタックフレームが増加するにつれて、JVM設定の-Xss値よりも総和が大きくなると、StackOverFlowErrorが放出されます.
OOM全行程OutOfMemoryErrorはいくつかの状況に分けられる可能性がある.
≪ヒープ・メモリ・オーバーフロー|Heap MemoryError|oem_src≫:作成したオブジェクトにヒープ・メモリ領域をインスタンス化して割り当てる必要がある場合、ヒープの占有量が-Xmxで設定された最大値に達すると、OutOfMemoryErrorが放出されます.
メソッド領域メモリオーバーフロー:クラスローダがclassファイルをメモリにロードすると、JVMはクラス名、アクセス修飾子、定数プール、フィールド記述、メソッド記述などを含むクラス情報をメソッド領域に抽出します.この場合、これらのクラス情報を格納する必要がありますが、メソッド領域のメモリ消費量が最大値に達した場合、OutOfMemoryErrorが放出されます.
次の2つの例を示します.
  //     OOM
  public void heapException(){  
      for(;;) {  
          ArrayList list = new ArrayList (2000);  
      }
  }

  //     SOF
  int count = 1;  
  public void stackException(){  
      count++;  
      this.stackException();  
  }