web-dev-qa-db-ja.com

最大コールスタックサイズ超過エラー

Direct Web Remoting(DWR)JavaScriptライブラリファイルを使用していますが、Safari(デスクトップおよびiPad)でのみエラーが発生します。

それは言う

最大コールスタックサイズを超えました。

このエラーは正確にはどういう意味ですか、それは処理を完全に停止しますか?

またSafariブラウザのための任意の修正(実際にはiPad Safariに、それは言う

JS:実行がタイムアウトを超えました

私は同じコールスタックの問題であると思います)

426
testndtv

つまり、あなたのコードのどこかで、あなたが呼び出しスタックの限界に達するまで、あなたは他の関数を呼び出すというような関数を呼び出しているということです。

これはほとんどの場合、満たされていない基本ケースを持つ再帰関数のためです。

スタックを見る

このコードを考えてください...

(function a() {
    a();
})();

これが一握りの呼び出しの後のスタックです...

Web Inspector

ご覧のとおり、呼び出しスタックは制限に達するまで増加します。ブラウザのハードコードされたスタックサイズまたはメモリの枯渇です。

それを修正するために、あなたの再帰関数が満たすことができる基本ケースを持っていることを確認してください...

(function a(x) {
    // The following condition 
    // is the base case.
    if ( ! x) {
        return;
    }
    a(--x);
})(10);
519
alex

同じJavaScriptファイルを誤って2回インポートまたは埋め込んだ場合は、これが発生することがあります。インスペクタの[リソース]タブで確認する価値があります。

73
lucygenik

私の場合は、値の代わりに入力要素を送信していました。

$.post( '',{ registerName: $('#registerName') } )

の代わりに:

$.post( '',{ registerName: $('#registerName').val() } )

これは私のChromeタブを凍らせてページが応答しなくなったときの 'Wait/Kill'ダイアログさえ表示していませんでした...

35
FKasa

コードのどこかに再帰的なループがあります(つまり、スタックがいっぱいになるまで、結局それ自身を繰り返し呼び出す関数)。

他のブラウザはより大きなスタックを持っているか(それであなたは代わりにタイムアウトになる)、あるいは何らかの理由でエラーを飲み込む(たぶんひどく配置されたtry-catch)。

エラーが発生したときにデバッガを使用して呼び出しスタックをチェックします。

27
Aaron Digulla

私の場合は、次のようにしてラージバイト配列を文字列に変換していました。

String.fromCharCode.apply(null, new Uint16Array(bytes))

bytesは数百万のエントリを含んでいましたが、これはスタックに収まるには大きすぎます。

11
Nate Glenn

スタックオーバーフローを検出する際の問題は、スタックトレースがほどけて、実際に何が起こっているのかがわからないことです。

私はこれに役立つChromeの新しいデバッグツールのいくつかを見つけました。

Performance tabを叩いて、Javascript samplesが有効になっていることを確認してください。

オーバーフローが発生している場所は明らかです。 extendObjectをクリックすると、実際にコードの正確な行番号を見ることができます。

enter image description here

また、役に立つかもしれないし、そうでないかもしれないタイミング、あるいはニシンを見ることもできます。

enter image description here


あなたが実際に問題を見つけることができないならば、もう一つの役に立つトリックはあなたが問題があると思うところにたくさんのconsole.logステートメントを置くことです。上記の前のステップはこれを助けることができます。

Chromeでは、同じデータを繰り返し出力すると、このように表示され、問題がより明確になります。この場合、スタックは最終的にクラッシュする前に7152フレームをヒットしました。

enter image description here

10
Simon_Weaver

私の場合は、clickイベントが子要素に伝播していました。だから、私は以下を入れなければなりませんでした:

e.stopPropagation()

クリックイベント:

 $(document).on("click", ".remove-discount-button", function (e) {
           e.stopPropagation();
           //some code
        });
 $(document).on("click", ".current-code", function () {
     $('.remove-discount-button').trigger("click");
 });

これがHTMLコードです。

 <div class="current-code">                                      
      <input type="submit" name="removediscountcouponcode" value="
title="Remove" class="remove-discount-button">
   </div>
6
Shahdat

何らかの理由で無限のプロセス/再帰を実行する必要がある場合は、別のスレッドでWebワーカーを使用できます。 http://www.html5rocks.com/en/tutorials/workers/basics/

dOM要素を操作して再描画したい場合は、animation http://creativejs.com/resources/requestanimationframe/ を使用してください。

5
Dr. Dama

Chromeデベロッパーツールバーのコンソールでエラーの詳細を確認してください。これにより、コールスタック内の関数が表示され、エラーの原因となっている再帰へと導きます。

5
chim

私の場合は、2つのjQueryモーダルが積み重なって表示されていました。それを防ぐことで私の問題は解決しました。

2
Barry Guvenkaya

これにより、Maximum call stack size exceededエラーが発生することもあります。

var items = [];
[].Push.apply(items, new Array(1000000)); //Bad

こっちも一緒:

items.Push(...new Array(1000000)); //Bad

Mozilla Docs から:

ただし、この方法でapplyを使用すると、JavaScriptエンジンの引数の長さの制限を超える危険があります。引数が多すぎる(数万を超えると考えられる)関数を適用した場合の結果は、エンジンによって異なります(JavaScriptCoreには65536の引数制限がハードコードされています)動作)は指定されていません。一部のエンジンは例外をスローします。さらに有害なことに、他の関数は、適用される関数に実際に渡される引数の数を任意に制限します。この後者のケースを説明するために:そのようなエンジンに4つの引数の制限がある場合(実際の制限はもちろんかなり高い)、引数5、6、2、3が上記の例で適用するために渡されたかのようになります。完全な配列ではなく。

だから試してください:

var items = [];
var newItems = new Array(1000000);
for(var i = 0; i < newItems.length; i++){
  items.Push(newItems[i]);
}
1
bendytree

自分自身を呼び出す関数があるかどうかを確認してください。例えば

export default class DateUtils {
  static now = (): Date => {
    return DateUtils.now()
  }
}
0
onmyway133

ここのほとんどすべての答えは、これが無限ループによってのみ引き起こされることができると述べています。そうではありません。そうでなければ、深くネストされた呼び出しによってスタックをオーバーランさせる可能性があります(それが効率的であると言うわけではありませんが、それは確かに可能な範囲内です)。 JavaScript VMを管理している場合は、スタックサイズを調整できます。例えば:

node --stack-size=2000

以下も参照してください。 Node.jsの最大呼び出しスタックサイズを増やすにはどうすればよいですか

0
ghayes

同じ問題に出くわしましたが、バベルを非難し始めたのは何が悪いのか理解できませんでした;)

ブラウザで例外を返さないコードがある:

if (typeof document.body.onpointerdown !== ('undefined' || null)) {

問題がひどく作成されました|| (または)babelとしての部分は、独自のタイプチェックを作成します。

function _typeof(obj){if(typeof Symbol==="function"&&_typeof(Symbol.iterator)==="symbol")

だから削除

|| null

babel transpilationを機能させました。

0
Raphael

Googleマップを使用している場合は、緯度経度がnew google.maps.LatLngに渡されているかどうかを確認します。私の場合、それらは未定義として渡されていました。

0
User-8017771

同じ名前の2つのJS関数があるため、このエラーが発生しました

0
iceDragon

再帰関数はchromeブラウザで見つけることができ、ctrl + shift + jを押してからsourceタブを押すと、コードのコンパイルの流れがわかり、コード内でブレークポイントを使用して見つけることができます。

0
Vishal Patel

私はまた、ドロップダウンロゴアップロードボックスを使用してロゴをアップロードするときの詳細がここにある同様の問題に直面しました

<div>
      <div class="uploader greyLogoBox" id="uploader" flex="64" onclick="$('#filePhoto').click()">
        <img id="imageBox" src="{{ $ctrl.companyLogoUrl }}" alt=""/>
        <input type="file" name="userprofile_picture"  id="filePhoto" ngf-select="$ctrl.createUploadLogoRequest()"/>
        <md-icon ng-if="!$ctrl.isLogoPresent" class="upload-icon" md-font-set="material-icons">cloud_upload</md-icon>
        <div ng-if="!$ctrl.isLogoPresent" class="text">Drag and drop a file here, or click to upload</div>
      </div>
      <script type="text/javascript">
          var imageLoader = document.getElementById('filePhoto');
          imageLoader.addEventListener('change', handleImage, false);

          function handleImage(e) {
              var reader = new FileReader();
              reader.onload = function (event) {

                  $('.uploader img').attr('src',event.target.result);
              }
              reader.readAsDataURL(e.target.files[0]);
          }
      </script>
      </div>

CSS.css

.uploader {
  position:relative;
  overflow:hidden;
  height:100px;
  max-width: 75%;
  margin: auto;
  text-align: center;

  img{
    max-width: 464px;
    max-height: 100px;
    z-index:1;
    border:none;
  }

  .drag-drop-zone {
    background: rgba(0, 0, 0, 0.04);
    border: 1px solid rgba(0, 0, 0, 0.12);
    padding: 32px;
  }
}

.uploader img{
  max-width: 464px;
  max-height: 100px;
  z-index:1;
  border:none;
}



.greyLogoBox {
  width: 100%;
  background: #EBEBEB;
  border: 1px solid #D7D7D7;
  text-align: center;
  height: 100px;
  padding-top: 22px;
  box-sizing: border-box;
}


#filePhoto{
  position:absolute;
  width:464px;
  height:100px;
  left:0;
  top:0;
  z-index:2;
  opacity:0;
  cursor:pointer;
}

修正前は私のコードは次のようでした。

function handleImage(e) {
              var reader = new FileReader();
              reader.onload = function (event) {
                  onclick="$('#filePhoto').click()"
                  $('.uploader img').attr('src',event.target.result);
              }
              reader.readAsDataURL(e.target.files[0]);
          }

コンソールのエラー:

enter image description here

Divタグからonclick="$('#filePhoto').click()"を削除することで解決しました。

0
spacedev

下記の同一のコードの呼び出しは両方とも1減少した場合、私のコンピュータ上のChrome 32で動作します。そのまま実行すると、エラー「RangeError:最大呼び出しスタックサイズを超えました」が生成されます。この制限はハードコードされているのではなく、あなたのマシンのハードウェアに依存しているようです。関数として呼び出された場合、この自主的な制限は、メソッドとして呼び出された場合よりも高い、すなわち、この特定のコードは、関数として呼び出されたときにより少ないメモリを使用するように思われる。

メソッドとして呼び出されます。

var ninja = {
    chirp: function(n) {
        return n > 1 ? ninja.chirp(n-1) + "-chirp" : "chirp";
    }
};

ninja.chirp(17905);

関数として呼び出されました:

function chirp(n) {
    return n > 1 ? chirp( n - 1 ) + "-chirp" : "chirp";
}

chirp(20889);
0
Elijah Lynn

私の場合の問題は、私は子供が親と同じパスでルーティングするためです。

const routes: Routes = [
  {
    path: '',
    component: HomeComponent,
    children: [
      { path: '', redirectTo: 'home', pathMatch: 'prefix' },
      { path: 'home', loadChildren: './home.module#HomeModule' },
    ]
  }
];

だから私は子供たちのルートの行を削除する必要がありました

const routes: Routes = [
  {
    path: '',
    component: HomeComponent,
    children: [
      { path: 'home', loadChildren: './home.module#HomeModule' },
    ]
  }
];
0
Amine Harbaoui

最近取り組んでいる管理サイトにフィールドを追加しました - contact_type ...簡単ですね。さて、もしあなたがselect "type"を呼び出してjquery ajax呼び出しを通してそれを送信しようとするとjquery.jsに深く埋め込まれたこのエラーで失敗します:これをしないでください:

$.ajax({
    dataType: "json",
    type: "POST",
    url: "/some_function.php",
    data: { contact_uid:contact_uid, type:type }
});

問題はその型です:type - 引数 "type"を命名しているのだと思います - typeという名前の値変数を持つことは問題ではありません。これを次のように変更しました。

$.ajax({
    dataType: "json",
    type: "POST",
    url: "/some_function.php",
    data: { contact_uid:contact_uid, contact_type:type }
});

そしてsome_function.phpを適宜書き直しました - 問題は解決しました。

0
Scott

私の場合は、このエラーがajax呼び出しで発生し、その変数を渡しようとしたデータが定義されていないため、このエラーが表示されますが、定義されていない変数は説明されません。私は、変数nが値を取得することを定義しました。

0
asifaftab87

私はこのスレッドが古いことを知っています、しかし、私はそれが他の人を助けることができるように私がこの問題を見つけたシナリオに言及する価値があると思います。

次のような要素がネストしているとします。

<a href="#" id="profile-avatar-picker">
    <span class="fa fa-camera fa-2x"></span>
    <input id="avatar-file" name="avatar-file" type="file" style="display: none;" />
</a>

子要素のイベントは、その親のイベントの内部では操作できません。例外がスローされるまで再帰的な呼び出しを行います。

そのため、このコードは失敗します。

$('#profile-avatar-picker').on('click', (e) => {
    e.preventDefault();

    $('#profilePictureFile').trigger("click");
});

これを回避するには2つの方法があります。

  • 子を親の外側に移動します。
  • 子要素に stopPropagation 関数を適用します。
0
Weslley Ramos

私は同じ問題に直面していました私はそれがajaxで2回使用されていたフィールド名を削除することによってそれを解決しました。

    jQuery.ajax({
    url : '/search-result',
    data : {
      searchField : searchField,
      searchFieldValue : searchField,
      nid    :  nid,
      indexName : indexName,
      indexType : indexType
    },
.....
0