StackOverflowError
日本語 | 積み上げ溢れ異常 |
英語 | stack overflow error |
ふりがな | すたっくおーばーふろーえらー |
フリガナ | スタックオーバーフローエラー |
J2SEに含まれるクラスのひとつ。パッケージも含めたクラス名はjava.lang.StackOverflowError。
実行中にメモリのスタック領域を使い切った場合に投げられるクラス。Errorクラスのサブクラスのため厳密には例外ではない。
ローカル変数を格納するメモリ領域を「スタック領域」と言う。
スタック領域はデフォルトで512Kバイトあり、まず使い切ることはないが、再帰呼び出しを行い、それが無限ループに陥った場合には発生することがある。
「スタック領域が足りないために発生した」とも読み取れるが、ほとんどの場合、スタックを完全に消費するようなプログラムは誤ったプログラムのため、設計を見直した方がいいだろう。
インスタンスは「ヒープ領域」という異なるメモリ領域に確保される。
通常、ローカル変数よりインスタンスの方がメモリを多く消費するため、このクラスよりも先にOutOfMemoryErrorクラスが投げられることの方が多いだろう。
実行中にメモリのスタック領域を使い切った場合に投げられるクラス。Errorクラスのサブクラスのため厳密には例外ではない。
ローカル変数を格納するメモリ領域を「スタック領域」と言う。
スタック領域はデフォルトで512Kバイトあり、まず使い切ることはないが、再帰呼び出しを行い、それが無限ループに陥った場合には発生することがある。
「スタック領域が足りないために発生した」とも読み取れるが、ほとんどの場合、スタックを完全に消費するようなプログラムは誤ったプログラムのため、設計を見直した方がいいだろう。
インスタンスは「ヒープ領域」という異なるメモリ領域に確保される。
通常、ローカル変数よりインスタンスの方がメモリを多く消費するため、このクラスよりも先にOutOfMemoryErrorクラスが投げられることの方が多いだろう。
参考サイト
// Sample.java
public class Sample
{
public static void main( String[] args )
{
// 再帰呼びするメソッドを呼び出します。
// ストッパーがないので無限ループします。
Sample sample = new Sample();
sample.recursiveMethod( 0 );
// 1
// (略)
// 279
}
/**
* 再帰呼び出しするメソッド。
*/
private void recursiveMethod( int i )
{
try
{
// iをインクリメントします。
++i;
long l001 = 100;
long l002 = 100;
long l003 = 100;
long l004 = 100;
long l005 = 100;
long l006 = 100;
long l007 = 100;
long l008 = 100;
long l009 = 100;
long l010 = 100;
long l011 = 100;
long l012 = 100;
long l013 = 100;
long l014 = 100;
long l015 = 100;
long l016 = 100;
long l017 = 100;
long l018 = 100;
long l019 = 100;
long l020 = 100;
long l021 = 100;
long l022 = 100;
long l023 = 100;
long l024 = 100;
long l025 = 100;
long l026 = 100;
long l027 = 100;
long l028 = 100;
long l029 = 100;
long l030 = 100;
long l031 = 100;
long l032 = 100;
long l033 = 100;
long l034 = 100;
long l035 = 100;
long l036 = 100;
long l037 = 100;
long l038 = 100;
long l039 = 100;
long l040 = 100;
long l041 = 100;
long l042 = 100;
long l043 = 100;
long l044 = 100;
long l045 = 100;
long l046 = 100;
long l047 = 100;
long l048 = 100;
long l049 = 100;
long l050 = 100;
long l051 = 100;
long l052 = 100;
long l053 = 100;
long l054 = 100;
long l055 = 100;
long l056 = 100;
long l057 = 100;
long l058 = 100;
long l059 = 100;
long l060 = 100;
long l061 = 100;
long l062 = 100;
long l063 = 100;
long l064 = 100;
long l065 = 100;
long l066 = 100;
long l067 = 100;
long l068 = 100;
long l069 = 100;
long l070 = 100;
long l071 = 100;
long l072 = 100;
long l073 = 100;
long l074 = 100;
long l075 = 100;
long l076 = 100;
long l077 = 100;
long l078 = 100;
long l079 = 100;
long l080 = 100;
long l081 = 100;
long l082 = 100;
long l083 = 100;
long l084 = 100;
long l085 = 100;
long l086 = 100;
long l087 = 100;
long l088 = 100;
long l089 = 100;
long l090 = 100;
long l091 = 100;
long l092 = 100;
long l093 = 100;
long l094 = 100;
long l095 = 100;
long l096 = 100;
long l097 = 100;
long l098 = 100;
long l099 = 100;
long l100 = 100;
// iを出力。
System.out.println( i );
// そして、自分自身を呼び出します。
// これが再帰呼び出しになります。
recursiveMethod( i );
}
catch( StackOverflowError e )
{
e.printStackTrace();
// java.lang.StackOverflowError
// at Sample.recursiveMethod(Sample.java:22)
// at Sample.recursiveMethod(Sample.java:128)
// at Sample.recursiveMethod(Sample.java:128)
// (略)
// at Sample.recursiveMethod(Sample.java:128)
// at Sample.recursiveMethod(Sample.java:128)
// at Sample.main(Sample.java:8)
// Exception in thread "main"
// このように、再帰呼び出しでスタックを食い潰すと
// 発生します。
// newで作成するインスタンスは、スタックに
// 置かれないのでスタックを消費しません。ただし、
// そのインスタンスの参照値を格納する参照型変数は
// スタックに確保されるので、こちらはスタックを
// 消費します。
}
}
}
public class Sample
{
public static void main( String[] args )
{
// 再帰呼びするメソッドを呼び出します。
// ストッパーがないので無限ループします。
Sample sample = new Sample();
sample.recursiveMethod( 0 );
// 1
// (略)
// 279
}
/**
* 再帰呼び出しするメソッド。
*/
private void recursiveMethod( int i )
{
try
{
// iをインクリメントします。
++i;
long l001 = 100;
long l002 = 100;
long l003 = 100;
long l004 = 100;
long l005 = 100;
long l006 = 100;
long l007 = 100;
long l008 = 100;
long l009 = 100;
long l010 = 100;
long l011 = 100;
long l012 = 100;
long l013 = 100;
long l014 = 100;
long l015 = 100;
long l016 = 100;
long l017 = 100;
long l018 = 100;
long l019 = 100;
long l020 = 100;
long l021 = 100;
long l022 = 100;
long l023 = 100;
long l024 = 100;
long l025 = 100;
long l026 = 100;
long l027 = 100;
long l028 = 100;
long l029 = 100;
long l030 = 100;
long l031 = 100;
long l032 = 100;
long l033 = 100;
long l034 = 100;
long l035 = 100;
long l036 = 100;
long l037 = 100;
long l038 = 100;
long l039 = 100;
long l040 = 100;
long l041 = 100;
long l042 = 100;
long l043 = 100;
long l044 = 100;
long l045 = 100;
long l046 = 100;
long l047 = 100;
long l048 = 100;
long l049 = 100;
long l050 = 100;
long l051 = 100;
long l052 = 100;
long l053 = 100;
long l054 = 100;
long l055 = 100;
long l056 = 100;
long l057 = 100;
long l058 = 100;
long l059 = 100;
long l060 = 100;
long l061 = 100;
long l062 = 100;
long l063 = 100;
long l064 = 100;
long l065 = 100;
long l066 = 100;
long l067 = 100;
long l068 = 100;
long l069 = 100;
long l070 = 100;
long l071 = 100;
long l072 = 100;
long l073 = 100;
long l074 = 100;
long l075 = 100;
long l076 = 100;
long l077 = 100;
long l078 = 100;
long l079 = 100;
long l080 = 100;
long l081 = 100;
long l082 = 100;
long l083 = 100;
long l084 = 100;
long l085 = 100;
long l086 = 100;
long l087 = 100;
long l088 = 100;
long l089 = 100;
long l090 = 100;
long l091 = 100;
long l092 = 100;
long l093 = 100;
long l094 = 100;
long l095 = 100;
long l096 = 100;
long l097 = 100;
long l098 = 100;
long l099 = 100;
long l100 = 100;
// iを出力。
System.out.println( i );
// そして、自分自身を呼び出します。
// これが再帰呼び出しになります。
recursiveMethod( i );
}
catch( StackOverflowError e )
{
e.printStackTrace();
// java.lang.StackOverflowError
// at Sample.recursiveMethod(Sample.java:22)
// at Sample.recursiveMethod(Sample.java:128)
// at Sample.recursiveMethod(Sample.java:128)
// (略)
// at Sample.recursiveMethod(Sample.java:128)
// at Sample.recursiveMethod(Sample.java:128)
// at Sample.main(Sample.java:8)
// Exception in thread "main"
// このように、再帰呼び出しでスタックを食い潰すと
// 発生します。
// newで作成するインスタンスは、スタックに
// 置かれないのでスタックを消費しません。ただし、
// そのインスタンスの参照値を格納する参照型変数は
// スタックに確保されるので、こちらはスタックを
// 消費します。
}
}
}
// Sample.java public class Sample { public static void main( String[] args ) { // 再帰呼びするメソッドを呼び出します。 // ストッパーがないので無限ループします。 Sample sample = new Sample(); sample.recursiveMethod( 0 ); // 1 // (略) // 279 } /** * 再帰呼び出しするメソッド。 */ private void recursiveMethod( int i ) { try { // iをインクリメントします。 ++i; long l001 = 100; long l002 = 100; long l003 = 100; long l004 = 100; long l005 = 100; long l006 = 100; long l007 = 100; long l008 = 100; long l009 = 100; long l010 = 100; long l011 = 100; long l012 = 100; long l013 = 100; long l014 = 100; long l015 = 100; long l016 = 100; long l017 = 100; long l018 = 100; long l019 = 100; long l020 = 100; long l021 = 100; long l022 = 100; long l023 = 100; long l024 = 100; long l025 = 100; long l026 = 100; long l027 = 100; long l028 = 100; long l029 = 100; long l030 = 100; long l031 = 100; long l032 = 100; long l033 = 100; long l034 = 100; long l035 = 100; long l036 = 100; long l037 = 100; long l038 = 100; long l039 = 100; long l040 = 100; long l041 = 100; long l042 = 100; long l043 = 100; long l044 = 100; long l045 = 100; long l046 = 100; long l047 = 100; long l048 = 100; long l049 = 100; long l050 = 100; long l051 = 100; long l052 = 100; long l053 = 100; long l054 = 100; long l055 = 100; long l056 = 100; long l057 = 100; long l058 = 100; long l059 = 100; long l060 = 100; long l061 = 100; long l062 = 100; long l063 = 100; long l064 = 100; long l065 = 100; long l066 = 100; long l067 = 100; long l068 = 100; long l069 = 100; long l070 = 100; long l071 = 100; long l072 = 100; long l073 = 100; long l074 = 100; long l075 = 100; long l076 = 100; long l077 = 100; long l078 = 100; long l079 = 100; long l080 = 100; long l081 = 100; long l082 = 100; long l083 = 100; long l084 = 100; long l085 = 100; long l086 = 100; long l087 = 100; long l088 = 100; long l089 = 100; long l090 = 100; long l091 = 100; long l092 = 100; long l093 = 100; long l094 = 100; long l095 = 100; long l096 = 100; long l097 = 100; long l098 = 100; long l099 = 100; long l100 = 100; // iを出力。 System.out.println( i ); // そして、自分自身を呼び出します。 // これが再帰呼び出しになります。 recursiveMethod( i ); } catch( StackOverflowError e ) { e.printStackTrace(); // java.lang.StackOverflowError // at Sample.recursiveMethod(Sample.java:22) // at Sample.recursiveMethod(Sample.java:128) // at Sample.recursiveMethod(Sample.java:128) // (略) // at Sample.recursiveMethod(Sample.java:128) // at Sample.recursiveMethod(Sample.java:128) // at Sample.main(Sample.java:8) // Exception in thread "main" // このように、再帰呼び出しでスタックを食い潰すと // 発生します。 // newで作成するインスタンスは、スタックに // 置かれないのでスタックを消費しません。ただし、 // そのインスタンスの参照値を格納する参照型変数は // スタックに確保されるので、こちらはスタックを // 消費します。 } } }