[JavaScript] 콜 스택과 메모리 힙 관련 이슈

배고픈메꾸리·2020년 12월 21일
2

Advanced JavaScript

목록 보기
3/10

스택 오버플로우(Stack Overflow)

앞서서 콜 스택은 간단한 변수나 작업들을 저장하여 코드의 어느 부분을 실행하는지 트래킹 하기 위해 설계된 공간이라고 배웠다.
스택 오버플로우란 말 그대로 스택이 오버플로우 됐다는 뜻이다. 특정 작업을 수행하면서 pop 하지 않고 계속해서 push 만 할 경우 한정된 공간의 크기를 넘어서게 되는데 이를 스택 오버플로우 라고 한다.

function inception(){
  inception()
}

inception 함수는 자기 자신을 호출하는 재귀 함수인데 이러한 재귀 함수는 유의해서 사용하지 않으면 스택 오버플로우를 쉽게 유발할 가능성이 있다.


가비지 컬렉터(Garbage Collector)

콜 스택과 마찬가지로 메모리 힙 또한 유한한 크기를 가지고 있다. 그렇기에 우리는 공간을 효율적으로 관리할 필요가 있다. 가비지 컬렉터는 사용하지 않는 변수나 함수를 종료후에 메모리 힙에서 제거하는 역할을 한다. 필요한 데이터만 메모리 힙에 저장함으로써 메모리의 여유 공간을 확보하는 것이다.

가비지 컬렉터가 있으니까 메모리 관리에 소홀해도 된다는 착각을 불러일으키기 쉽지만 이 또한 인간이 개발한 프로그램이기 때문에 완벽하지 않다. 그렇다면 이 가비지 컬렉터는 어떻게 작동할까?

가비지 컬렉터는 마크 앤 스윕 알고리즘을 사용해서 작동한다.

왼쪽의 Root Set을 변수라고 생각해보자. 변수는 어떠한 객체를 가리킬 수 있고 객체또한 다른 객체를 가리킬 수 있다. 이때 참조당하지 않는 object 5 , 7 , 8 은 가비지 컬렉터에 의해서 제거된다. (파이썬의 레퍼런스 카운트 방식과 동일하다)


메모리 누수(Memory Leak)

메모리 누수란 이름에서도 알 수 있듯 제공된 메모리 공간의 범위를 넘어서서 데이터가 저장되는 현상이다. 참조는 되고있지만 쓰지는 않는 데이터들이 많을 경우 가비지 컬렉터가 지우지 못하고 계속해서 메모리를 낭비하기 때문에 발생할 수 있다.

무한 루프를 제외하고 메모리 누수가 빈번하게 발생하는 3가지 패턴이 있다.

  1. 전역 변수를 많이 만든다
var a = 1;
var b = 2;
. . .

예제에서는 간단한 변수만 선언했지만 참조에 참조를 이은 복잡한 전역 변수를 많이 만들게 되면 메모리의 낭비가 발생하고 메모리 누수를 유발할 수 있다.

  1. 이벤트 리스너
var element = document.getElementById('button');
element.addEventListner('click',onClick)

이벤트 리스너는 가장 흔한 메모리 누수 유발 원인이다. 특정 상황에서만 실행되기 때문에 이러한 코드가 메모리를 차지하고 있다는 것 자체를 까먹는 경우가 많고 그로인해 이벤트 리스너는 메모리에서 하염없이 이벤트를 기다리는 현상이 발생한다.

(SPA에서 같은 페이지를 반복하면 이벤트 리스너가 계속해서 중첩되는 현상이 있어서 메모리 사용량이 증가한다고 하는데 자세한건 찾아봐야겠다.)

  1. setInterval() 함수는 일정 주기마다 작업을 수행하도록 등록되기 때문에 계속해서 메모리 공간을 차지하게 된다.
profile
FE 개발자가 되자

0개의 댓글