본문 바로가기
language/javascript

♻️ 가비지 컬렉션(GC) 작동 원리와 메모리 누수 방지 전략

by 죄니안죄니 2025. 5. 11.

♻️ 가비지 컬렉션(GC) 작동 원리와 메모리 누수 방지 전략

자바스크립트는 메모리를 자동으로 관리해주는 가비지 컬렉션(Garbage Collection) 기능을 내장하고 있습니다.
그러나 자동이라고 해서 완벽하지는 않으며, 실수로 인해 메모리 누수(memory leak)가 발생할 수 있습니다.
이번 글에서는 GC의 작동 원리와 함께, 실무에서 자주 발생하는 누수 사례와 예방 방법을 정리합니다.


1. 자바스크립트의 메모리 구조

  • 스택(Stack): 함수 호출과 지역 변수 저장 (고정 크기, 빠른 할당)
  • 힙(Heap): 객체, 배열 등 동적 데이터 저장 (GC 대상)

가비지 컬렉션은 힙 영역의 메모리 정리를 담당하며, 더 이상 사용되지 않는 객체를 자동으로 해제합니다.


2. GC의 기본 원리 – 참조 카운트와 도달 가능성

✅ 오래된 방식: 참조 카운트


let a = {};
let b = a;
a = null;
// b가 여전히 a를 참조하므로 GC 대상 아님

✅ 현재는 대부분 “도달 가능성(Reachability)” 기준

루트 객체(window, globalThis)에서부터 도달할 수 없는 객체는 GC 대상이 됩니다.


let user = {
  name: "Alice"
};
user = null; // 👉 객체에 접근할 수 있는 경로가 사라짐 → GC 대상

3. 메모리 누수(Memory Leak)란?

더 이상 사용되지 않지만 해제되지 않고 메모리에 남아 있는 객체가 계속해서 누적되는 현상입니다.

💥 대표적인 누수 예시

  • 1️⃣ 전역 변수에 계속 값 저장
  • 2️⃣ 이벤트 리스너를 제거하지 않음
  • 3️⃣ 클로저 내부에 불필요한 참조 유지
  • 4️⃣ DOM 요소 제거 후 참조 유지

4. 실무 예제: 누수 발생과 해결

❌ 누수 예시: 클로저로 인한 참조 유지


function setup() {
  const bigData = new Array(1000000).fill("x");
  return () => console.log("ready");
}

const handler = setup(); // bigData는 아직 메모리에 있음

✅ 해결: 불필요한 참조 제거


function setup() {
  let bigData = new Array(1000000).fill("x");
  const callback = () => console.log("ready");
  bigData = null; // 수동으로 참조 제거
  return callback;
}

5. 이벤트 리스너 해제는 필수


const el = document.querySelector("#btn");
el.addEventListener("click", onClick);

// 이후 버튼 제거
el.remove(); // ❌ 이벤트 리스너가 참조되고 있으면 GC 안 됨

// ✅ 리스너 먼저 제거
el.removeEventListener("click", onClick);
el.remove();

🧠 이벤트 핸들러, 타이머, 인터벌은 꼭 clear 또는 remove 해야 합니다.


6. WeakMap, WeakSet을 활용한 안전한 참조 관리


const cache = new WeakMap();

function remember(obj, value) {
  cache.set(obj, value); // obj가 GC 되면 함께 사라짐
}
  • key가 객체인 경우만 사용 가능
  • 객체가 참조에서 사라지면 자동으로 메모리에서 제거됨

7. 메모리 누수 방지 체크리스트 ✅

  • 전역 변수 남용 금지 (let x 대신 필요한 스코프에 한정)
  • setTimeout, setInterval 해제 (clearTimeout, clearInterval)
  • 이벤트 리스너 제거 (removeEventListener)
  • DOM 제거 시 객체 참조도 제거
  • 대용량 배열, Map 등 클로저에서 오래 유지하지 않기
  • WeakMap, WeakSet 활용

📌 마무리

자바스크립트의 가비지 컬렉션은 자동이지만, 누수는 개발자의 책임입니다.
도달 가능성 기반의 GC가 작동하기 때문에, 참조가 끊기지 않으면 메모리는 남습니다.
이벤트, 클로저, 전역 변수 등 참조를 적절히 해제하고 관리하는 습관이 중요합니다.

다음 글에서는 클로저와 메모리 누수 이슈를 집중적으로 살펴보며, 함수형 구조 내에서의 안전한 메모리 사용법을 정리합니다.

댓글