■ 現在のこのページの役立ち度:
表示されない場合こちらのリンクからもご覧になれます。
|
■ このページの役立ち度を評価する:
役立ち度を評価してください。
(1(左):あまり役立たない - 5(右):大変役立った): |
■ ページの共有: |
[ サイト内検索 ]
![]()
カスタム検索
|
#2480-3スタック領域不足を解消するには?ミンスク2002-08-26(月) 01:50
#2513-3RE#2480:スタック領域不足を解消するには?K.J.K.2002-08-26(月) 13:39
#2518-2RE#2513:スタック領域不足を解消するには?ミンスク2002-08-27(火) 01:03
#2520-3RE#2518:スタック領域不足を解消するには?レベル112002-08-27(火) 01:41
#2521-3RE#2518:スタック領域不足を解消するには?K.J.K.2002-08-27(火) 01:45
#2523-3RE#2521:スタック領域不足を解消するには?Imo2002-08-27(火) 02:06
#2529-3RE#2520:スタック領域不足を解消するには?ミンスク2002-08-27(火) 03:09
#2530-3RE#2521:スタック領域不足を解消するには?ミンスク2002-08-27(火) 03:10
#2531-3RE#2530:スタック領域不足を解消するには?Dental2002-08-27(火) 03:15
#2534-3RE#2530:スタック領域不足を解消するには?K.J.K.2002-08-27(火) 04:10
#2558-2RE#2534:スタック領域不足を解消するには?ミンスク2002-08-28(水) 00:24
#2513-3RE#2480:スタック領域不足を解消するには?K.J.K.2002-08-26(月) 13:39
#2518-2RE#2513:スタック領域不足を解消するには?ミンスク2002-08-27(火) 01:03
#2520-3RE#2518:スタック領域不足を解消するには?レベル112002-08-27(火) 01:41
#2521-3RE#2518:スタック領域不足を解消するには?K.J.K.2002-08-27(火) 01:45
#2523-3RE#2521:スタック領域不足を解消するには?Imo2002-08-27(火) 02:06
#2529-3RE#2520:スタック領域不足を解消するには?ミンスク2002-08-27(火) 03:09
#2530-3RE#2521:スタック領域不足を解消するには?ミンスク2002-08-27(火) 03:10
#2531-3RE#2530:スタック領域不足を解消するには?Dental2002-08-27(火) 03:15
#2534-3RE#2530:スタック領域不足を解消するには?K.J.K.2002-08-27(火) 04:10
#2558-2RE#2534:スタック領域不足を解消するには?ミンスク2002-08-28(水) 00:24
ミンスク2002-08-26(月) 01:50
SQL Serverのテーブルから大量レコード(万単位)を読み込んで テキストファイルに書き出すプログラムをVB6.0で作りました。 当初は6万レコードくらい読み込めましたが、冗長性のあるロジックを Subプロシージャにまとめた結果、実行途中で「スタック領域が不足しています」と出ます。 MSDNライブラリで調べた結果、原因は、FunctionまたはSubプロシージャの 呼び出し回数が多すぎるためだと予想されます。 何度か試した結果、不思議なことが分かりました。 それは、読み込みレコードが何万件であっても、処理終了付近でスタック領域不足になることです。 しかも、ある特定のSubプロシージャ呼び出しの部分で、スタック領域不足になります。 例えば、2万件レコード読み込みの場合、約1万9千件まで読み込めます。 3万件レコード読み込みの場合、約2万8千件まで読み込めます。 4万件レコード読み込みの場合、約3万8千件まで読み込めます。 つまり、ある特定のレコード件数に依存するのではなく、何万件であろうと処理終了付近で スタック領域不足になるのです。こういう場合、どうすればいいのか教えて下さい。
ミンスク2002-08-27(火) 01:03
> その[終了付近]のどこのコードでエラーが発生しているのかを調べてみては。 ですから、最初の投稿で書いたとおり、いつも決まって某Subプロシージャを 呼び出す部分で「Error28 スタック領域不足」というエラーが出ます。 某Subプロシージャでは、更に別のSubプロシージャを呼び出して、 それがまた別のSubプロシージャを呼び出す、という2段構えの呼び出しをしています。 ロジックの冗長性を無くすために、こういう呼び出し構成にしています。 で、MSDNを読むと、原因はプロシージャ呼び出しの数が多すぎると書いてますが、 冗長性のロジックをSubプロシージャにしないと後々の改修も困難ですし、 しかもSQLServerからの読み込みレコードは常に万単位ですし、 ジレンマに陥っています。。。どう解決すればいいのか、わかりません。 ちなみにプロシージャの再帰呼び出しは、していません。 たぶん確実な方法として、冗長性があってSubプロシージャにしている部分を、 バカみたいにメインプロシージャに記述すれば、呼び出し回数が減るので、 スタック領域不足エラーは起こらないと思います。 でも、そうすると、何のためのSubプロシージャなのか、意味がないですよね? こういう経験をしたVBプログラマは、他にいらっしゃらないのでしょうか?
レベル112002-08-27(火) 01:41
> ですから、最初の投稿で書いたとおり、いつも決まって某Subプロシージャを > 呼び出す部分で「Error28 スタック領域不足」というエラーが出ます。 > 某Subプロシージャでは、更に別のSubプロシージャを呼び出して、 > それがまた別のSubプロシージャを呼び出す、という2段構えの呼び出しをしています。 > ロジックの冗長性を無くすために、こういう呼び出し構成にしています。 > > で、MSDNを読むと、原因はプロシージャ呼び出しの数が多すぎると書いてますが、 原因はそれ以外にあと4つ、書かれていますよね?これらの原因については? > 冗長性のロジックをSubプロシージャにしないと後々の改修も困難ですし、 > しかもSQLServerからの読み込みレコードは常に万単位ですし、 > ジレンマに陥っています。。。どう解決すればいいのか、わかりません。 残念ながら、そのテの障害は、コードを見ないことにはどうにもなりません。 掲示板の手に負えないと思います。 > でも、そうすると、何のためのSubプロシージャなのか、意味がないですよね? 何の為にSubプロシージャを使うか?の問題ですね。 文面を見た感じ、メインのコードが冗長的だから「仕方なく」Subを使って分割したかの様に 感じました。 そもそもSubを使う目的は、コードの再利用化であって、分割ではありません。 コードを再利用する事によって、その副効果としてコードが短くなるのです。 そういった意味では どちらにしろ意味がありません。 > こういう経験をしたVBプログラマは、他にいらっしゃらないのでしょうか? そういう経験かどうかは微妙ですが、データが大量過ぎて処理が遅くなったり した事(フリーズしているかの様な錯覚に)は多々あります。 数万件ものデータを扱う部分をストアドにするなりして回避しては? と、いうか、扱うべきデータは最小限に抑える努力をすべきかも知れません。
K.J.K.2002-08-27(火) 01:45
> 某Subプロシージャでは、更に別のSubプロシージャを呼び出して、 > それがまた別のSubプロシージャを呼び出す、という2段構えの呼び出しをしています。 > ロジックの冗長性を無くすために、こういう呼び出し構成にしています。 別に、それぐらいで問題が起きることはないと思います。 > で、MSDNを読むと、原因はプロシージャ呼び出しの数が多すぎると書いてますが、 本当にそれが原因なのでしょうか? VSを立ち上げて、そこでDebugしてみたときに、そのスタックの深度はどれ ぐらいになっていますか? そこでとんでもない深さになっているのならば、 原因がそれだと言えます。ですから、まずはそれで確認してみるとか。 また、プロシージャ内で使っている変数の大きさの総数はどれぐらいなので しょうか? そちらの方が可能性は大きいのではないでしょうか? 固定長文字列 などはかなり喰います。
スタックは、 Do For Sub Function GoSub などで起こります。 すべて1づつ増えます。これのループの数がある一定以上の数になるとエラーを起こします。 再帰を使うプログラムではすぐ不足してしまいます。 Windowsフォルダに設定をかえれるファイルがあると聞いたことがありますが…。
ミンスク2002-08-27(火) 03:09
> > で、MSDNを読むと、原因はプロシージャ呼び出しの数が多すぎると書いてますが、 > 原因はそれ以外にあと4つ、書かれていますよね?これらの原因については? 固定長文字列とDoEventsは、全然使っていません。 「ローカル変数の必要領域不足」はよく分かりませんが、そんなに多く使ってないつもりです。 「コードでイベント連鎖発生」は意味がよくわかりません。 「呼び出し履歴」ダイアログボックスというのも、説明を読んでも、表示方法がわかりません。 > 文面を見た感じ、メインのコードが冗長的だから「仕方なく」Subを使って > 分割したかの様に感じました。 > そもそもSubを使う目的は、コードの再利用化であって、分割ではありません。 私の場合、「分割」も目的ですし、「再利用化」も目的です。 ちなみに、分割する前は、何万レコードの読み込みでもOKでした。 Subプロシージャに分割したとたんに、スタック領域不足エラーになったため、 呼び出し回数の多さが原因かと思っています。 > 数万件ものデータを扱う部分をストアドにするなりして回避しては? > と、いうか、扱うべきデータは最小限に抑える努力をすべきかも知れません。 すみません、他のシステムと勘違いしていましたが、 入力レコードはSQLServerではなく、CSVファイルでした。申し訳ありません。 ユーザーの要求により、何万レコードもあるCSVファイルを、 分割せずに1回の操作で処理したいと言われたのです。
ミンスク2002-08-27(火) 03:10
> > で、MSDNを読むと、原因はプロシージャ呼び出しの数が多すぎると書いてますが、 > 本当にそれが原因なのでしょうか? Subプロシージャの数を増やす前は、何万件のレコードの読み込みでも正常終了しました。 Subプロシージャの数を増やした結果、スタック領域不足エラーが発生したので、 これが原因としか思えません。 > VSを立ち上げて、そこでDebugしてみたときに、そのスタックの深度はどれ > ぐらいになっていますか? そこでとんでもない深さになっているのならば、 > 原因がそれだと言えます。ですから、まずはそれで確認してみるとか。 すみません・・・スタックの深度とは、どうやって知るのでしょうか? MSDNの説明にあった、「呼び出し履歴」ダイアログボックスというのが見つかりません。 MSDNに書いてある説明が、初心者のため、よくわからないのです。 > また、プロシージャ内で使っている変数の大きさの総数はどれぐらいなので > しょうか? そちらの方が可能性は大きいのではないでしょうか? 固定長文字列 > などはかなり喰います。 変数の大きさの総数とは、どうやって調べるのでしょうか? ちなみに、固定長文字列は1個も使ってません。
Dental2002-08-27(火) 03:15
> MSDNの説明にあった、「呼び出し履歴」ダイアログボックスというのが見つかりません。 Ctrl + L で。
K.J.K.2002-08-27(火) 04:10
# 全角・半角文字の使い分けは適切に。 > Subプロシージャの数を増やした結果、スタック領域不足エラーが発生したので、 > これが原因としか思えません。 特定のプロシージャを呼び出そうとするときに起こるのですから、 そのプロシージャにエラーを引き起こすなにかしらの原因がある、 と考える方が自然じゃないでしょうか。 単純に考えると、そのプロシージャ内で使う変数の領域を確保する ことができなかった、ということだと思います。 > 変数の大きさの総数とは、どうやって調べるのでしょうか? そのプロシージャの中で、 Dim ... As ... は全部で幾つでしょうか? 全部がLong型ならば、x4ですよね。 > ちなみに、固定長文字列は1個も使ってません。 固定長配列も注意です。ユーザー定義型も場合によっては。 で、DoEventsを使ってはいない、と書いてありましたが、外部の コンポーネントを使うことは、しばし同等のコードを実行している ことになることもあります。 どこでスタックを多量消費しているのか、を調べるのか、が解決の 糸口になるでしょう。VSのデバッグ機能を駆使すれば特定できると 思われます。
ミンスク2002-08-28(水) 00:24
お騒がせしてすみません。解決しましたので報告致します。 原因と解決策を以下に書きます。 (改修前の状態) SubプロシージャA(終了処理でBを呼び出す) SubプロシージャB(終了処理でCを呼び出す) SubプロシージャC(終了処理でAを呼び出す) 但し、Aの中で判定文があり、ある条件を満たした場合は、 Bを呼び出さずにプログラムを終了します。 つまり、無限ループにはなりません。 更に言えば、Bの処理の途中で、SubプロシージャDと SubプロシージャEを呼び出すというロジックがあります。 (改修後の状態) SubプロシージャSを作り、その中でAもBもCも 呼び出すような作りにしました。 つまり、Sは制御プロシージャ的な作りにしました。 その結果、何万件の読み込みレコードでも、 スタック領域不足エラーは発生しなくなりました。 とまあ、簡単に言えば、制御プロシージャを作らずに、 イモヅル的なプロシージャ呼び出しの作りにしたことが、 スタック領域不足エラーの原因だったわけです。 お騒がせしました。初心者ゆえの初歩的ミスと思ってお許し下さい。
このページと関連する記事:
#1587-1スタック領域について。1999-07-17(土) 18:44#21732-0大雑把すぎてすみません2002-07-25(木) 13:52
#448-2プロパティ参照の高速化2001-10-24(水) 10:56
#38115-0スタック領域の計測のしかたについて2001-02-02(金) 09:18
#43519-0RE#43517:スタック領域の不足2001-05-30(水) 09:29
#16425-0スタックオーバーについて2000-02-18(金) 13:53
#99-2RE#98:スタックエラーについて2003-04-23(水) 17:39
#34119-0スタック領域について2000-11-26(日) 12:51
#896-0スタック領域が不足1999-08-19(木) 14:08
#26303-0DoEventsでのスタック不足2000-07-23(日) 11:00