[解決済み] Node.js - 最大コールスタックサイズを超えました。
2022-02-07 21:59:34
質問
私のコードを実行すると、Node.js は
"RangeError: Maximum call stack size exceeded"
例外は再帰呼び出しが多すぎることが原因です。私は、Node.js のスタックサイズを
sudo node --stack-size=16000 app
しかし、Node.jsはエラーメッセージなしにクラッシュします。sudoを使わずにもう一度実行すると、Node.jsは以下のように表示されます。
'Segmentation fault: 11'
. 再帰的な呼び出しを削除せずに、これを解決する可能性はありますか?
どのように解決するのですか?
再帰的な関数呼び出しをラップして
-
setTimeout
, -
setImmediate
または -
process.nextTick
関数を使用して、node.js にスタックをクリアする機会を与えてください。もし、これを行わず、多くのループで
リアル
非同期関数の呼び出しや、コールバックを待たない場合、あなたの
RangeError: Maximum call stack size exceeded
になります。
必然的に
.
非同期ループの可能性」については、多くの記事があります。 以下はその一つです。 .
では、さらにいくつかのサンプルコードを紹介します。
// ANTI-PATTERN
// THIS WILL CRASH
var condition = false, // potential means "maybe never"
max = 1000000;
function potAsyncLoop( i, resume ) {
if( i < max ) {
if( condition ) {
someAsyncFunc( function( err, result ) {
potAsyncLoop( i+1, callback );
});
} else {
// this will crash after some rounds with
// "stack exceed", because control is never given back
// to the browser
// -> no GC and browser "dead" ... "VERY BAD"
potAsyncLoop( i+1, resume );
}
} else {
resume();
}
}
potAsyncLoop( 0, function() {
// code after the loop
...
});
これは正しい。
var condition = false, // potential means "maybe never"
max = 1000000;
function potAsyncLoop( i, resume ) {
if( i < max ) {
if( condition ) {
someAsyncFunc( function( err, result ) {
potAsyncLoop( i+1, callback );
});
} else {
// Now the browser gets the chance to clear the stack
// after every round by getting the control back.
// Afterwards the loop continues
setTimeout( function() {
potAsyncLoop( i+1, resume );
}, 0 );
}
} else {
resume();
}
}
potAsyncLoop( 0, function() {
// code after the loop
...
});
このループは、1ラウンドごとに少し時間(ブラウザの1ラウンドトリップ)を失うので、遅すぎるかもしれません。しかし
setTimeout
を毎回使用します。通常は1000回に一度でよいでしょう。ただし、スタックの大きさによっては、この限りではない。
var condition = false, // potential means "maybe never"
max = 1000000;
function potAsyncLoop( i, resume ) {
if( i < max ) {
if( condition ) {
someAsyncFunc( function( err, result ) {
potAsyncLoop( i+1, callback );
});
} else {
if( i % 1000 === 0 ) {
setTimeout( function() {
potAsyncLoop( i+1, resume );
}, 0 );
} else {
potAsyncLoop( i+1, resume );
}
}
} else {
resume();
}
}
potAsyncLoop( 0, function() {
// code after the loop
...
});
関連
-
[解決済み】最大呼び出しスタックサイズ超過エラー
-
[解決済み】エラー TRK0005: 位置特定に失敗しました。"CL.exe"
-
[解決済み] バルク更新を行う。
-
[解決済み] Node.jsのプログラムにコマンドライン引数を渡すにはどうしたらいいですか?
-
[解決済み] Node.jsを使うタイミングをどう判断するか?
-
[解決済み] Node.jsで終了する方法
-
[解決済み] Node.jsでファイルを書き込む
-
[解決済み] Node.jsアプリケーションをデバッグするにはどうすればよいですか?
-
[解決済み] Node.jsで環境変数を読み込む
-
[解決済み] Node.jsでファイル/ディレクトリが存在するかどうかを同期的にチェックする
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Node.jsのホスト名/IPが証明書のaltnamesと一致しない。
-
[解決済み】「RangeError: 最大呼び出しスタックサイズを超えました」なぜ?
-
[解決済み】「npm install」と「npm rebuild」の違いとは?
-
[解決済み】Mongooseで、日付でソートするにはどうしたらいいですか?(node.js)
-
[解決済み] Heroku "状態が起動から停止に変更されました SIGTERMで全プロセスを停止"
-
[解決済み] ReferenceError: describe は定義されていません NodeJs
-
[解決済み] NodeJsのSequelizeでautoIncrementはどのように動作するのですか?
-
[解決済み] バルク更新を行う。
-
[解決済み] 再帰から反復への道
-
[解決済み】setImmediateとnextTickの比較