[Javascript] memory leak

chosh·2023년 2월 20일
5

자바스크립트 내에서 메모리 누수에 대해 알아보려고 합니다.

Memory lifecycle

메모리 할당 -> 메모리 사용 -> 메모리 해제
javascript는 high-level language 이기 때문에 메모리 사용이 끝나면 가비지컬렉터(GC)에 의해 메모리가 해제 됩니다.

자바스크립트의 저장소는 힙(heap)과 스택(stack) 두가지가 있습니다.
원시값은 스택에 저장이 되고, 참조값은 힙에 저장이 됩니다.

  • 원시값: number, string, boolean, null, undefined, bigint, symbol
  • 참조값: array, object, function

이때, 참조값을 가르키는 주소는 스택에 저장되며,
참조값이 가르키는 주소들은 힙에 저장 됩니다.

garbage collector

가비지 컬렉터는 더 이상 사용하지 않는 메모리를 수거하는 역할을 합니다.
가비지 컬렉터가 더 이상 사용하지 않는 메모리를 찾는 두가지 알고리즘이 있습니다.

  • reference count
  • mark-and-sweep

reference count 알고리즘은, 참조를 더이상 하지 않는 메모리를 수거해갑니다.
하지만 순환참조를 하게 된다면, 참조값을 가르키는 주소(스택에 있는 값)를 null로 바꿔서 참조를 해제 하더라도 reference count 알고리즘은 힙에 저장된 데이터를 수거 할 수 없습니다.
이 문제는 mark-and-sweep 으로 해결이 가능 합니다.

mark-and-sweep 알고리즘은 javascript 내에서 전역객체를 주기적으로 체크합니다.
도달가능한 모든 객체에 active 마크를 표시하고, active 마크를 받지 않은 메모리는 해제시키기 때문에, 도달 할 수 없는 null 처리된 메모리를 수거하는 것 입니다.

memory leak 의 원인

1. 우발적인 변수 선언

전역 객체에 선언된 값은 mark-and-sweep 알고리즘에서 항상 active 이기 때문에, 가비지 컬렉터가 수거해갈 수 없습니다.
자바스크립트는 선언되지 않은 변수의 처리를 허용하고 있으며,
선언 되지 않은 참조는 전역 객체 내부에 변수를 만듭니다.

예를 들면

function foo() {
  this.message = "test" // 함수 선언식은 this가 동적으로 결정되며, 내부함수에서 선언될 경우 전역 객체에 바인딩 됨
}
foo()

와 같이 사용하면 foo가 없어지더라도, message는 남아있게 됩니다.

우발적인 변수를 선언하지 않도록 하기 위해서는 use strict 모드로 설정해 엄격한 체크를 하도록 하는 방법이 있습니다.

2. Closures

클로저는 내부함수가 외부 함수의 스코프에 접근해서 값을 참조할 수 있습니다.
함수 스코프에 있는 값은 콜스택에서 빠져 나올때 메모리를 수거해가지만, 클로저에서 참조하고 있는 값은 메모리에 계속 남아있게 되어 메모리 누수를 유발 할 수 있습니다.

클로저 사용은 불가피 하기 때문에 값이 사용되거나 반환되는지 확인해야 됩니다.

3. 잊어버린 Timer

setTimeout 은 시간이 경과되면 함수가 실행되고 끝입니다.
하지만 setInterval 은 주어진 시간동안 계속 반복하여 실행됩니다. 그렇기 때문에 메모리 누수를 유발 할 수 있습니다.

이런 누수를 방지하기 위해서는 호출 내부에 참조를 제공하고, clear 시켜줘야 됩니다.

4. Dom의 외부 참조

dom을 지워도, 메모리 상에는 남아 있는 경우가 있습니다.
이 부분은 코드를 보고 이해하는게 빠르기 때문에 아래 참고자료의
How to excape from memory leakOut of DOM reference 부분을 참고하세요

크롬 개발자도구를 이용한 메모리 누수 체크

Heap 이나 Node 등의 메모리 체크

개발자 도구 -> Performance -> Memory 체크 -> 좌측에 동그라미 버튼 클릭-> 그래프 확인

분리된 Dom 확인

개발자도구 -> Memory -> Take snapshot 클릭 -> Detached filter -> 분리된거 확인


참고자료

How to excape from memory leak
상황에 따른 this 바인딩

profile
제가 참고하기 위해 만든 블로그라 글을 편하게 작성했습니다. 틀린거 있다면 댓글 부탁드립니다.

0개의 댓글