Maksimum çağrı yığını boyutu aşıldı hatası


533

Direct Web Remoting (DWR) JavaScript kitaplık dosyası kullanıyorum ve yalnızca Safari'de (masaüstü ve iPad) bir hata alıyorum

Diyor ki

Maksimum arama yığını boyutu aşıldı.

Bu hata tam olarak ne anlama geliyor ve tamamen işlenmeyi durduruyor mu?

Ayrıca herhangi bir düzeltme SafariAslında tarayıcıyla ( iPad Safari, diyor

JS: yürütme zaman aşımını aştı

hangi aynı çağrı yığını sorunu olduğunu varsayalım)


2
Ben dataajax aracılığıyla , değişkenler (onları bildirmeden) göndermeye çalışırken bu hatayı aldım . Değişkenleri bildirerek hata düzeltildi.
phpfresher

Yanıtlar:


621

Bu, kodunuzda bir yerde, çağrı yığını sınırına ulaşana kadar başka bir işlevi çağıran bir işlevi çağırdığınız anlamına gelir.

Bu neredeyse her zaman karşılanmayan bir temel vaka ile özyinelemeli bir işlevden kaynaklanır.

Yığını görüntüleme

Bu kodu düşünün ...

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

İşte bir avuç görüşmeden sonra yığın ...

Web Denetçisi

Gördüğünüz gibi, çağrı yığını bir sınıra ulaşana kadar büyür: tarayıcı sabit kodlu yığın boyutu veya bellek tükenmesi.

Düzeltmek için, özyinelemeli işlevinizin karşılanabilecek bir temel kasaya sahip olduğundan emin olun ...

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

6
Bunun için çok teşekkürler ... Yani yığın sınırının tükenmekte olduğu herhangi bir yol / araç var ... Yine de, bu büyük bir kütüphane dosyası olduğu ve benim tarafımdan oluşturulmadığı için, nerede olduğunun tamamen farkında değilim işler yanlış gidiyor olabilir ..
testndtv

52
@Oliver Bir işlevi yaklaşık 300 trilyon kez çalıştırmanız gerekiyorsa, muhtemelen yanlış bir şey yapıyorsunuzdur.
ceejayoz

3
@Oliver - dinamik programlamaya bakmak isteyebilirsiniz - sanırım o kadar çok benzersiz çözümünüz yok, adımları tekrarlıyorsunuz, bu yüzden ikinci dereceden ziyade polinum zaman için programlamanız gerekebilir. en.wikipedia.org/wiki/Dynamic_programming
newshorts

4
@Akhoy Düzenli bir işlevde evet, ancak özyinelemeli bir işlev düşünün. Bir başkasını (kendisi) çağırır ve eskisinin dönüş adresini yığına bırakır (aksi takdirde PC nereye gideceğini nereden bilebilir?) Bu, elbette her seferinde bir dönüş adresini yığının üzerine iterek tekrar arar. Gelecek yüzyılda gerçekleşmesi muhtemel olmayan bir temel dava nedeniyle bu durum kaçtığında, bir yığın taşması olur.
alex

5
Kodunuz aynı verimsiz segmenti 134217728 kez çalıştırır. Şaka yapmıyorum yavaş. 9 seviye döngüyü tek bir döngü seviyesine açabilmek için bitsel operatörler kullanmalısınız.
Jack Giffin

82

Bazen, aynı JavaScript dosyasını yanlışlıkla iki kez içe aktarırsanız / eklerseniz, denetçinin kaynaklar sekmesinde kontrol etmeye değer olabilir.


9
Bu sorun genellikle yanlışlıkla aynı JS dosyasını iki kez içe / dışa aktardığınızda oluşur. Özyinelemeli döngüye neden olan kesin süreç, spekülasyon yapmak istediğim bir şey değildir, ancak aynı geçiş ağ geçidinden 100mph'de iki özdeş arabayı sürmek gibi bir şey olduğunu varsayabilirim.
lucygenik

3
Ben öyle düşünmüyorum. Aynı türden iki işlev veya değişken gömülü ise, ikincisi önceki tanımları geçersiz kılar.
ssudaraka

Evet ... Neden olduğunu ya da sürecin ne olduğunu gerçekten bilmiyorum, ben de geçersiz kılacaktı.
lucygenik

Partiye biraz geç, ancak kodun herhangi bir fonksiyonun dışında olduğu zaman, her ikisinin de iki JS dosyasında yürütüldüğünü ve muhtemelen herhangi bir fonksiyonun dışında oldukları için birinin üzerine yazmayacağını düşünürdüm.
Cillian Collins

1
@lucygenik bir dahaki sefere gönderilerinizde trol düzenlemelerini onaylarken daha dikkatli olmak istiyorsunuz. Bu gönderi neredeyse spam olarak silindi (kontrol geçmişi)
Jean-François Fabre

56

Benim durumumda, değerleri yerine giriş öğeleri gönderiyordum:

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

Onun yerine:

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

Bu, Chrome sekmemi, sayfanın yanıt vermediği zaman bana 'Bekle / Öldür' iletişim kutusunu göstermediği bir noktaya kadar dondu ...


3
Acaba neden böyle bir hata için bir istisna yok ... Teşekkürler!
Džuris

Çok teşekkürler, bu beni kurtardı
Eme Hado

Bunu olası bir çözüm olarak eklemek üzereydim. Ben sadece bu kesin şeyi lol yaptım
Michael Buchok

31

Kodunuzda bir yerde özyinelemeli bir döngü vardır (yani, yığın dolana kadar kendini tekrar tekrar çağıran bir işlev).

Diğer tarayıcıların ya daha büyük yığınları vardır (bunun yerine zaman aşımına uğrarsınız) ya da bir nedenden dolayı hatayı yutuyorlar (belki de kötü yerleştirilmiş bir try-catch).

Hata oluştuğunda çağrı yığınını kontrol etmek için hata ayıklayıcıyı kullanın.


Cevabınız için çok teşekkürler. IE / FF'de, kod iyi çalışıyor gibi görünüyor ... Sadece masaüstü Safari ve iPad Safari'de hatayı alıyorum. Aslında JS dosyası benim yaratım değil, bir kütüphane dosyası (DWR engine.js'den) .. directwebremoting.org Ayrıca "çağrı yığınını kontrol etmek için hata ayıklayıcı" derken, Safari Inspector kullanarak bunu nasıl yapabilirim?
testndtv

Safari Müfettiş ile hiçbir deneyimim yok. JavaScript hata ayıklayıcısını açmayı ve sayfanızı yüklemeyi deneyin. Eşleşmeyen bir hata atıldığında hata ayıklayıcı durmalıdır. Bu işe yaramazsa, süper kullanıcı veya web yöneticilerine sorun (sayfanın altına bakın)
Aaron Digulla

aynı adı taşıyan 2 işlevi vardı !! DOH!
jharris8567

16

Stackoverflow'ları tespit etme ile ilgili problem bazen yığın izinin gevşemesidir ve gerçekte neler olduğunu göremezsiniz.

Chrome'un bazı yeni hata ayıklama araçlarını bunun için yararlı buldum.

Düğmesine basın, etkin Performance tabolduğundan emin olun Javascript samplesve böyle bir şey alırsınız.

Taşmanın burada olduğu oldukça açık! Üzerine extendObjecttıklarsanız, koddaki tam satır numarasını görebilirsiniz.

resim açıklamasını buraya girin

Ayrıca yararlı olabilecek veya olmayabilecek zamanlamaları veya kırmızı bir ringa balığı görebilirsiniz.

resim açıklamasını buraya girin


Sorunu gerçekten bulamıyorsanız bir başka yararlı hile, sorunun console.logolduğunu düşündüğünüz yere çok sayıda ifade koymaktır . Yukarıdaki önceki adım size bu konuda yardımcı olabilir.

Chrome'da tekrar tekrar aynı verileri çıkarırsanız, sorunun daha net olduğu yeri gösteren şekilde görüntülenir. Bu durumda, yığın nihayet çökmeden önce 7152 kareyi vurdu:

resim açıklamasını buraya girin


13

Benim durumumda, büyük bir bayt dizisini aşağıdakileri kullanarak bir dizeye dönüştürüyordum:

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

bytes yığına sığmayacak kadar büyük birkaç milyon girdi içeriyordu.


Ben de aynı çizgi ile aynı sorunu vardı! thanx
ksh

büyük bayt dizisi dönüştürmek için en iyi çözüm nedir ??
ksh

6
@KarthikHande Bunu bir çağrı yerine bir for döngüsü içinde yapmanız gerekir. var uintArray = new Uint16Array(bytes); var converted = []; uintArray.forEach(function(byte) {converted.push(String.fromCharCode(byte))});
Nate Glenn

JSON dönüştürmek nasıl? JSON.parse denedim ama işe yaramadı ... Ben Uintl8Array kullanıyorum
ksh

@KarthikHande Bütün problemi görmeden söyleyemem. Lütfen tüm detayları içeren başka bir soru açın.
Nate Glenn

6

Benim durumumda, alt öğe üzerinde tıklama olayı yayılıyor. Bu yüzden aşağıdakileri koymak zorunda kaldım:

e.stopPropagation ()

tıklama etkinliğinde:

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

İşte html kodu:

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

5

Chrome geliştirici araç çubuğu konsolundaki hata ayrıntılarını kontrol edin, bu size çağrı yığınındaki işlevleri verecektir ve sizi hataya neden olan özyinelemede yönlendirecektir.



3

Buradaki neredeyse her cevap, bunun sadece sonsuz bir döngüden kaynaklanabileceğini belirtir. Bu doğru değil, aksi takdirde yığını derinden iç içe çağrılarla aşırı çalıştırabilirsiniz (bunun etkili olduğunu söylemek değil, ama kesinlikle mümkün olan yerde). JavaScript VM'niz üzerinde kontrolünüz varsa, yığın boyutunu ayarlayabilirsiniz. Örneğin:

node --stack-size=2000

Ayrıca bkz: Node.js dosyasındaki maksimum çağrı yığını boyutunu nasıl artırabilirim?


2

Benim durumumda, iki jQuery modals üst üste yığılmış gösteriliyordu. Bunu önlemek sorunumu çözdü.


2

Son zamanlarda üzerinde çalıştığımız bir yönetici sitesine bir alan ekledik - contact_type ... kolay değil mi? Eğer "type" seçeneğini seçerseniz ve bunu jquery ajax çağrısı ile göndermeye çalışırsanız, jquery.js'de gömülü olan bu hatayla başarısız olur. Bunu yapma:

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

Sorun şudur: type: type - bize "type" argümanını isimlendirdiğimize inanıyorum - type adlı bir değer değişkenine sahip olmak sorun değildir. Bunu şu şekilde değiştirdik:

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

Ve buna göre some_function.php yazdı - problem çözüldü.


1

Kendini çağıran bir işleviniz olup olmadığını kontrol edin. Örneğin

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

1

Bu ayrıca bir Maximum call stack size exceededhataya neden olabilir :

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

Burada aynı:

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

Gönderen Mozilla Dokümanlar :

Ancak dikkat: Uygulamayı bu şekilde kullanırken, JavaScript motorunun bağımsız değişken uzunluk sınırını aşma riskiniz vardır. Çok fazla bağımsız değişkeni olan bir işlevi uygulamanın sonuçları (on binlerce argümandan fazla düşünün) motorlar arasında farklılık gösterir (JavaScriptCore'un sabit kodlu argüman sınırı 65536'dır), çünkü sınır (hatta aşırı büyük yığınların doğası bile) davranış) belirtilmemiş. Bazı motorlar bir istisna atar. Daha da önemlisi, diğerleri keyfi olarak uygulanan işleve iletilen argüman sayısını sınırlandıracaktır. Bu son durumu göstermek için: eğer böyle bir motor dört argüman sınırına sahip olsaydı (gerçek sınırlar elbette önemli ölçüde daha yüksekse), yukarıdaki örneklerde uygulanacak 5, 6, 2, 3 argümanlarının geçirilmiş olması gibi olurdu, tam dizi yerine.

O zaman dene:

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

0

Bilgisayarımdaki Chrome 32'de 1 çalışmayla azalırsa aşağıdaki aynı kodun her iki çağrılması da örn. 17905 vs 17904. Olduğu gibi çalıştırılırsa "RangeError: Maksimum çağrı yığını boyutu aşıldı" hatasını verir. Bu sınır sabit kodlanmış değil, ancak makinenizin donanımına bağlıdır. Bir işlev olarak çağrıldığında, bu kendi kendine yüklenen sınırın bir yöntem olarak çağrıldığından daha yüksek olduğu, yani bu özel kodun bir işlev olarak çağrıldığında daha az bellek kullandığı görülmektedir.

Yöntem olarak çağrıldı:

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

ninja.chirp(17905);

İşlev olarak çağrıldı:

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

chirp(20889);

0

yinelemeli işlevinizi crome tarayıcıda bulabilir, ctrl + shift + j tuşlarına ve ardından kaynak sekmesi, kod derleme akışı sağlar ve koddaki kırılma noktasını kullanarak bulabilirsiniz.


Ancak bazen hatanın nereden kaynaklandığını bulmak zor olabilir. Sitemizde çok fazla JavaScript var.
Mathias Lykkegaard Lorenzen

0

Burada da benzer bir sorunla karşılaştım, açılır logo yükleme kutusunu kullanarak logo yüklerken ayrıntılar

<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;
}

düzeltmeden önce kodum:

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]);
          }

Konsoldaki hata:

resim açıklamasını buraya girin

onclick="$('#filePhoto').click()"Div etiketinden kaldırarak çözdüm.



0

Aynı sorunla karşı karşıya kaldım, ajax'ta iki kez kullanılan bir alan adını kaldırarak çözdüm.

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

0

Bu iş parçacığı eski biliyorum, ama ben başkalarına yardımcı olabilir bu yüzden bu sorunu buldum senaryo bahsetmeye değer olduğunu düşünüyorum.

Diyelim ki böyle iç içe öğeleriniz var:

<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>

Üst öğe olayındaki alt öğe olaylarını değiştiremezsiniz çünkü kendi kendine yayılır ve istisna atılıncaya kadar yinelemeli çağrılar yapar.

Yani bu kod başarısız olur:

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

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

Bundan kaçınmak için iki seçeneğiniz vardır:

  • Çocuğu ebeveynin dışına taşıyın.
  • Alt öğeye stopPropagation işlevini uygulayın .


0

Google haritalarla çalışıyorsanız, lat lng'nin aktarılıp aktarılmadığını kontrol edin new google.maps.LatLng. Benim durumumda tanımsız olarak geçiyorlardı.


0

Benim durumumdaki sorun, ben ebeveyn ile aynı yol ile çocuk rota var çünkü:

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

Bu yüzden çocuk rotasının hattını kaldırmak zorunda kaldım

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

0

benim durumumda bu hatayı ajax çağrısında alıyorum ve bu değişkeni iletmeye çalıştığım veriler tanımlanmadı, bu hatayı gösteriyor ama tanımlanmamış değişkeni tanımlamıyor. Ben değişken n değeri var tanımladı ekledi.


kendime benzer şekilde yakıldım, benim durumumda, değişken bir isim yazdım ... etkili bir şekilde aynı şeydi.
user2366842

0

Aynı sorunla karşılaştık, neyin yanlış olduğunu çözemedi Babil'i suçlamaya başladı;)

Kodların tarayıcılarda herhangi bir istisna döndürmemesi:

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

sorun kötü oluşturuldu || (veya) babil kendi tip kontrolünü oluştururken bölüm:

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

yani kaldırmak

|| null

babil transpilasyonu yaptı.


0

Benim durumumda ben yanlışlıkla aynı değişken adı ve val fonksiyonu "class_routine_id" atadı

var class_routine_id = $("#class_routine_id").val(class_routine_id);

şöyle olmalı:

 var class_routine_id = $("#class_routine_id").val(); 


0

React-Native 0.61.5 ile birlikte kullanıyorum ( npm 6.9.0 ve düğüm 10.16.1 )

Project'te yeni kütüphaneler yüklerken,

(örn. npm install @ tepki-navigasyon / yerel - kaydetme)

Maksimum çağrı yığını boyutu aşıldı hatası

bunun için deniyorum

sudo npm önbellek temiz - kuvvet

(Not: - Aşağıdaki komut npm önbellek boyutunuza bağlı olarak genellikle 1 ila 2 dakika sürer )


-1

Bazen dönüştürme veri türü nedeniyle oldu, örneğin dize olarak düşündüğünüz bir nesneniz var.

Soket.id nodejs içinde js istemcisinde örnek olarak bir dize değildir. onu dize olarak kullanmak için önce Dize kelimesini eklemeniz gerekir:

String(socket.id);

-1

Bu değişken bildirilmediğinde bir değişken, bir değer atamaya çalışıyordum.

Değişkeni bildirmek hatamı düzeltti.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.