development

최대 호출 스택 크기가 오류를 초과했습니다

big-blog 2020. 2. 15. 23:09
반응형

최대 호출 스택 크기가 오류를 초과했습니다


DWR (Direct Web Remoting) JavaScript 라이브러리 파일을 사용하고 있으며 Safari (데스크톱 및 iPad)에서만 오류가 발생합니다.

그것은 말한다

최대 통화 스택 크기를 초과했습니다.

이 오류는 정확히 무엇을 의미하며 완전히 처리를 중지합니까?

또한 대한 수정 Safari실제로에 브라우저 ( iPad Safari, 그것은 말한다

JS : 실행 시간 초과

내가 생각하는 것은 동일한 호출 스택 문제라고 가정합니다)


이는 코드의 어딘가에서 호출 스택 제한에 도달 할 때까지 다른 함수 등을 호출하는 함수를 호출한다는 것을 의미합니다.

이것은 거의 항상 기본 사례가 충족되지 않는 재귀 함수 때문입니다.

스택보기

이 코드를 고려하십시오 ...

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

몇 번의 호출 후 스택은 다음과 같습니다.

웹 검사기

보다시피, 호출 스택은 브라우저 하드 코딩 된 스택 크기 또는 메모리 소모와 같은 한계에 도달 할 때까지 증가합니다.

그것을 고치려면 재귀 함수에 기본 케이스가 있는지 확인하십시오 ...

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

실수로 동일한 자바 스크립트 파일을 실수로 두 번 가져 오기 / 포함하면 관리자의 리소스 탭에서 확인할 가치가 있습니다.


필자의 경우 값 대신 입력 요소를 전송했습니다.

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

대신에:

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

이렇게하면 Chrome 탭이 고정되어 페이지가 응답하지 않을 때 '대기 / 종료'대화 상자가 표시되지 않습니다 ...


코드 어딘가에 재귀 루프가 있습니다 (즉, 스택이 가득 찰 때까지 결국 스스로 호출하는 함수).

다른 브라우저는 더 큰 스택을 가지고 있기 때문에 대신 타임 아웃을 얻거나 어떤 이유로 오류를 삼킨다 (트립 캐치가 잘못되었을 수 있음).

오류가 발생하면 디버거를 사용하여 호출 스택을 확인하십시오.


필자의 경우 다음을 사용하여 큰 바이트 배열을 문자열로 변환했습니다.

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

bytes 스택에 맞추기에는 너무 큰 수백만 개의 항목이 포함되어 있습니다.


스택 오버플로 감지의 문제는 때때로 스택 추적이 풀리고 실제로 무슨 일이 일어나고 있는지 볼 수 없다는 것입니다.

Chrome의 최신 디버깅 도구 중 일부가 유용한 것으로 나타났습니다.

히트 Performance tab, 확인 Javascript samples가능하고이 같은 것을 얻을 것이다.

오버플로가 어디에 있는지는 분명합니다! 를 클릭 extendObject하면 실제로 코드에서 정확한 줄 번호를 볼 수 있습니다.

여기에 이미지 설명을 입력하십시오

도움이 될 수도 있고 아닐 수도있는 타이밍도 볼 수 있습니다.

여기에 이미지 설명을 입력하십시오


실제로 문제를 찾을 수없는 경우 유용한 또 다른 요령은 문제가 console.log있다고 생각되는 곳에 많은 진술을하는 것입니다. 위의 이전 단계가 도움이 될 수 있습니다.

Chrome에서 동일한 데이터를 반복적으로 출력하면 문제가 더 분명한 위치를 나타내는 다음과 같이 표시됩니다. 이 경우 스택은 마침내 충돌하기 전에 7152 프레임을 쳤습니다.

여기에 이미지 설명을 입력하십시오


필자의 경우 클릭 이벤트가 하위 요소에서 전파되었습니다. 그래서 다음을 넣어야했습니다.

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>

Chrome 개발자 툴바 콘솔에서 오류 세부 정보를 확인하면 호출 스택의 기능을 제공하고 오류를 일으키는 재귀를 안내합니다.


어떤 이유로 무한한 프로세스 / 재귀를 실행해야하는 경우 별도의 스레드에서 웹 작업자를 사용할 수 있습니다. http://www.html5rocks.com/en/tutorials/workers/basics/

돔 요소를 조작하고 다시 그리려면 애니메이션을 사용 하십시오 http://creativejs.com/resources/requestanimationframe/


필자의 경우 두 jQuery 모달이 서로 겹쳐 쌓여있는 것으로 나타났습니다. 그것을 막 으면 내 문제가 해결되었습니다.


자신을 호출하는 함수가 있는지 확인하십시오. 예를 들어

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

거의 모든 대답은 무한 루프에 의해서만 발생할 수 있다고 말합니다. 그것은 사실이 아니며, 그렇지 않으면 깊이 중첩 된 호출을 통해 스택을 오버런 할 수 있습니다 (효율적이라고 말할 수는 없지만 확실히 가능한 영역에 있습니다). JavaScript VM을 제어 할 수있는 경우 스택 크기를 조정할 수 있습니다. 예를 들면 다음과 같습니다.

node --stack-size=2000

참고 : Node.js에서 최대 호출 스택 크기를 늘리는 방법


최근 작업중인 관리자 사이트에 contact_type ... 쉬운 필드를 추가했습니다. 선택 "type"을 호출하고 jquery ajax 호출을 통해 보내려고하면 jquery.js에 깊이 묻혀있는이 오류로 실패합니다.

$.ajax({
    dataType: "json",
    type: "POST",
    url: "/some_function.php",
    data: { contact_uid:contact_uid, type: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를 다시 작성했습니다-문제가 해결되었습니다.


또한 Maximum call stack size exceeded오류가 발생할 수 있습니다 .

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

여기 동일합니다 :

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

로부터 모질라 문서 :

그러나 이런 식으로 적용하면 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]);
}

내 컴퓨터 (예 : 17905 대 17904)의 Chrome 32에서 1 번 감소한 경우 아래 동일한 코드를 모두 호출하면 "RangeError : Maximum call stack size exceeded"오류가 발생합니다. 이 한계는 하드 코딩 된 것이 아니라 컴퓨터의 하드웨어에 따라 다릅니다. 함수로 호출 된 경우이 자체 부과 한계는 메소드로 호출 된 경우보다 더 높습니다. 즉이 특정 코드는 함수로 호출 될 때 더 적은 메모리를 사용합니다.

메소드로 호출

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

crome 브라우저에서 재귀 함수를 찾고 ctrl + shift + j를 누른 다음 소스 탭을 누르면 코드 컴파일 플로우가 제공되며 코드에서 중단 점을 사용하여 찾을 수 있습니다.


드롭 다운 로고 업로드 상자를 사용하여 로고를 업로드 할 때의 세부 사항은 여기에서도 비슷한 문제에 직면했습니다.

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

콘솔의 오류 :

여기에 이미지 설명을 입력하십시오

onclick="$('#filePhoto').click()"div 태그에서 제거하여 해결했습니다 .


나는 같은 문제에 직면했다. 아약스에서 두 번 사용 된 필드 이름을 제거하여 해결했다.

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

이 스레드가 오래되었다는 것을 알고 있지만이 문제를 발견 한 시나리오를 언급 할 가치가 있다고 생각하여 다른 사람들을 도울 수 있습니다.

다음과 같이 중첩 요소가 있다고 가정하십시오.

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

이를 피하기 위해 두 가지 옵션이 있습니다.

  • 자녀를 부모 외부로 옮기십시오.
  • 자식 요소에 stopPropagation 함수를 적용하십시오 .

같은 이름을 가진 두 개의 JS 함수가 있기 때문에이 오류가 발생했습니다.


If you are working with google maps, then check if the lat lng are being passed into new google.maps.LatLng are of a proper format. In my case they were being passed as undefined.


The issue in my case is because I have children route with same path with the parent :

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

So I had to remove the line of the children route

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

in my case I m getting this error on ajax call and the data I tried to pass that variable haven't defined, that is showing me this error but not describing that variable not defined. I added defined that variable n got value.


Have come accross the same issue, coulnd't figured out what's wrong started blaming Babel ;)

Having code not returning any exception in browsers :

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

issue was badly created || (or) part as babel creates its own type check:

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

so removing

|| null

made babel transpilation worked.


Sometimes happened because of convert data type , for example you have an object that you considered as string.

socket.id in nodejs either in js client as example, is not a string. to use it as string you have to add the word String before:

String(socket.id);

I was trying to assign a variable, a value, when that variable had not been declared.

Declaring the variable fixed my error.


That worked for me

$('form')[0].submit()

T̶h̶i̶s̶ ̶c̶a̶n̶ ̶h̶a̶p̶p̶e̶n̶ ̶w̶h̶e̶n̶ ̶y̶o̶u̶ ̶t̶r̶y̶ ̶p̶u̶s̶h̶ ̶a̶n̶ ̶a̶r̶r̶a̶y̶ ̶i̶n̶t̶o̶ ̶i̶t̶ ̶i̶t̶s̶e̶l̶f̶.
let alerts = []; alerts.push(alerts);
Edit -
I was wrong. Thank you @melpomene for the correction.

I was getting the error in AWS cloud 9 console and removing the above code fixed the issue . I'll go back to the code and find out the real reason it got fixed and update it here.

참고 URL : https://stackoverflow.com/questions/6095530/maximum-call-stack-size-exceeded-error



반응형