본문 바로가기
language/javascript

♻️ 클로저와 메모리 누수 이슈 – 원인과 방지 방법 완전 정리

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

♻️ 클로저와 메모리 누수 이슈 – 원인과 방지 방법 완전 정리

자바스크립트에서 클로저(Closure)는 강력한 기능인 동시에 메모리 누수의 원인이 되기도 합니다.
이번 글에서는 클로저의 동작 원리를 간단히 정리하고, 실무에서 발생할 수 있는 누수 사례와 방지 팁을 소개합니다.


1. 클로저란?

클로저는 함수가 선언될 당시의 렉시컬 환경(변수 스코프)을 기억하여, 함수 실행 이후에도 참조를 유지하는 구조입니다.


function outer() {
  let count = 0;
  return function inner() {
    count++;
    return count;
  };
}

const counter = outer();
console.log(counter()); // 👉 1
console.log(counter()); // 👉 2

여기서 inner()outer()count 변수에 계속 접근 가능 → 클로저 형성


2. 왜 메모리 누수가 발생할까?

클로저가 변수의 참조를 계속 유지하기 때문에, GC가 객체를 수거하지 못하는 상황이 생깁니다.


function createHandler() {
  const largeData = new Array(1000000).fill("data");
  return function onClick() {
    console.log(largeData[0]);
  };
}

const handler = createHandler();
// 이제 largeData는 계속 메모리에 남아 있음

👉 handler가 유지되는 한, largeData는 절대 GC되지 않음


3. DOM 요소와 클로저 결합 시 주의


function attachEvent() {
  const element = document.querySelector("#btn");
  const huge = new Array(1000000).fill("🔥");

  element.addEventListener("click", () => {
    console.log(huge[0]);
  });
}

👉 이벤트 핸들러 내부에서 huge를 참조하기 때문에
해당 요소가 DOM에서 제거돼도 huge는 메모리에 남게 됨


4. 해결 방법 – 참조 명확히 해제

✅ 필요 없는 참조를 명시적으로 제거

function setup() {
  let temp = new Array(1000000).fill("💣");

  const clickHandler = () => {
    console.log("clicked");
  };

  temp = null; // ✅ 참조 해제
  return clickHandler;
}
✅ DOM에서 제거 전 이벤트 리스너 해제

el.removeEventListener("click", clickHandler);

5. 클로저 사용 시 메모리 안전한 패턴

  • ✅ 클로저 내부에서 필요한 변수만 캡처하세요.
  • 대용량 데이터는 외부로 분리하거나, 참조를 짧게 유지하세요.
  • ✅ 이벤트 리스너 등록 시 항상 제거 코드도 함께 작성하세요.

// 위험한 패턴
function cacheClosure() {
  const bigArray = new Array(1000000).fill("😱");
  return () => "ok"; // bigArray가 남아있음!
}

// 안전한 패턴
function safeClosure() {
  let bigArray = new Array(1000000).fill("👌");
  const f = () => "ok";
  bigArray = null;
  return f;
}

📌 마무리

클로저는 함수형 프로그래밍의 강력한 도구이지만, 참조 유지로 인한 메모리 누수를 유발할 수 있습니다.
실무에서는 클로저 내부에서 불필요한 객체를 참조하지 않도록 주의하고, 이벤트 리스너나 타이머와 함께 사용 시 꼭 해제 로직을 포함해야 합니다.

다음 글에서는 WeakMap을 활용한 안전한 참조 관리 전략과 실제 클로저/캐시 처리 방식에 대해 정리하겠습니다.

댓글