私は、再帰を介して大量のデータ、たとえば1000個の変数を渡すプログラムを持っています。再帰は少なくとも50回または60回実行されます。気になるのは、スペースが足りないためにメモリ位置にデータが上書きされる可能性があるか、メモリがない場合はプログラムメモリという例外が発生することです。不足していますか(そのようなエラーは発生していません)?
プログラムにメモリがなく、既存の場所で上書きされているため、間違った解決策が得られる可能性はありますか?
私は、再帰を介して大量のデータ、たとえば1000個の変数を渡すプログラムを持っています。再帰は少なくとも50回または60回実行されます。気になるのは、スペースが足りないためにメモリ位置にデータが上書きされる可能性があるか、メモリがない場合はプログラムメモリという例外が発生することです。不足していますか(そのようなエラーは発生していません)?
プログラムにメモリがなく、既存の場所で上書きされているため、間違った解決策が得られる可能性はありますか?
関係するストレージ領域には、スタックとヒープの2つがあります。スタックはメソッド呼び出しの現在の状態(つまりローカル変数と参照)が保持される場所であり、ヒープはオブジェクトが格納される場所です。ホットスポットのドキュメントによると、Linux 64ビットでは、各スレッドにデフォルトで1024kBのスタックがあります。ヒープは任意の大きさにすることができ、今日ではGBのオーダーになっています。
再帰的メソッドは、スタックとヒープの両方を使用します。どちらを最初に使い果たすかは、実装によって異なります。例として、数千の整数を必要とするメソッドを考えてみましょう。ローカル変数として宣言されている場合、つまり次のようになります。
public void stackOverflow() {
int a_1;
int a_2;
int a_3;
// ...
int a_10_000_000;
}
あなたのプログラムはStackOverflowError
。一方、整数を配列に編成する場合は、次のようになります。
public void outOfMemory() {
int[] integers = new int[10 * 1000 * 1000];
}
ヒープはまもなくいっぱいになり、プログラムは。で終了しますOutOfMemoryError
。どちらの場合も、メモリが破損したり、データが上書きされたりします。ただし、どちらの場合もコードは間違っており、何らかの方法で修正する必要があります。ただし、プログラムについて詳しく知る必要がある方法を説明します。
スペースが少ないため、メモリ位置にデータが上書きされる可能性はありますか?
Javaはオブジェクトをヒープスペースに格納し、それらの値はガベージコレクタによってのみ再利用されます。つまり、渡すのは参照であり、関数への値ではありません。変数をコピーしていないため、メモリを消費しません(ただし、スタックフレームを増やすことでメモリを増やします)。オブジェクトがスレッドスタックで参照されている場合、オブジェクトが上書きされる方法はありません。
[...]または、メモリがない場合は、プログラムのメモリが不足しているという例外が発生します
JVMがメモリを使い果たした場合、非同期例外(OutOfMemoryError )が発生しますが、ここで発生する唯一の例外は、再帰関数がそれ自体を何度も呼び出す場合のStackOverflowErrorです。
間違った結果が出る可能性はありません。stackoverflowの場合、プログラムはStackOverflowErrorで途中で終了します。
データを保存するメモリ位置は、他のもので上書きすることはできません。
Java、あるいはCの場合でも、プログラムメモリが無関係なメモリの状態を変更することはありません。
JVMは末尾再帰をサポートしていませんが。したがって、最大で、使用可能なスペースがなくなるとStackOverFlowErrorが発生します。データの破損について心配する必要はありませんが、再帰スタックが高すぎるかどうかを確認してください(たとえば2000を超える場合)。もしそうならそれに取り組む
2つのケースが考えられます
十分なメモリ、再帰が完了し、結果が得られます。
メモリが不足していないため、StackOverFlowErrorが発生し、プログラムが終了します
メモリの上書きが発生しないため、間違った結果になることはありません