본문 바로가기
카테고리 없음

메모리 누수(Memory Leak)는 왜 발생할까

by by_merry 2026. 5. 9.

가비지 컬렉션(GC)까지 이해하고 나면 자연스럽게 이런 의문이 생긴다. “메모리를 자동으로 정리해준다면서, 왜 메모리 누수 같은 문제가 생기는 걸까?” 나도 처음에는 이 부분이 꽤 헷갈렸다. 자동으로 정리된다면 메모리가 계속 쌓일 이유가 없어 보였기 때문이다. 그런데 실제로 프로그램을 오래 실행하다 보면 점점 느려지거나, 브라우저 탭 하나가 메모리를 몇 GB씩 먹는 상황도 종종 발생한다. 이게 바로 메모리 누수와 관련된 문제다.

메모리 누수는 ‘사용하지 않는데도 메모리가 계속 남아 있는 상태’다

메모리 누수(Memory Leak)는 말 그대로 필요 없는 메모리가 해제되지 않고 계속 남아 있는 현상을 의미한다. 중요한 건 “더 이상 필요 없는 데이터인데도 프로그램이 여전히 사용 중이라고 판단하는 상황”이라는 점이다.

예를 들어 어떤 객체를 만들고 실제로는 더 이상 사용하지 않는데, 코드 어딘가에서 여전히 참조하고 있으면 GC는 이 객체를 지울 수 없다. 왜냐하면 GC 입장에서는 “아직 사용 중인 객체”처럼 보이기 때문이다.

나도 예전에 웹페이지를 오래 켜두면 점점 느려지는 경험을 한 적이 있었다. 처음에는 그냥 브라우저 문제라고 생각했는데, 개발자 도구로 메모리 사용량을 확인해보니까 특정 객체들이 계속 남아 있었다. 결국 이벤트 리스너를 제대로 제거하지 않아서 생긴 문제였다.

그때 느낀 게 하나 있다. 메모리 누수는 “메모리를 많이 쓰는 것”이 아니라, “원래 없어져야 할 데이터가 계속 살아 있는 것”이라는 점이다.

GC가 있어도 메모리 누수가 발생하는 이유

많은 사람들이 GC가 있으면 메모리 누수가 아예 없어질 거라고 생각한다. 나도 처음에는 그렇게 생각했다. 하지만 GC는 “사용하지 않는 객체”만 정리할 수 있을 뿐이다.

즉, 프로그램이 실수로 계속 참조를 유지하고 있으면, GC는 그 객체를 지울 수 없다. 대표적인 예가:

  • 이벤트 리스너 제거 안 함
  • 전역 변수 계속 사용
  • 닫힌 페이지 객체 참조 유지
  • 캐시 데이터 무한 증가

같은 경우들이다.

특히 JavaScript 쪽에서는 이벤트 리스너 관련 메모리 누수가 정말 자주 나온다. 나도 예전에 버튼 클릭 이벤트를 계속 등록만 하고 제거하지 않았던 적이 있는데, 시간이 지나니까 페이지가 점점 무거워졌다.

그때는 코드가 “정상 동작”하니까 문제 없는 줄 알았다. 그런데 내부에서는 필요 없는 객체들이 계속 살아남고 있었던 것이다.

이 경험 이후로는 “잘 동작하는 코드”와 “메모리까지 안정적인 코드”는 완전히 다른 문제라는 걸 느끼게 됐다.

메모리 누수는 천천히 성능을 망가뜨린다

메모리 누수의 무서운 점은 바로 즉시 티가 나지 않는다는 점이다. 프로그램이 처음 실행될 때는 멀쩡하다. 하지만 시간이 지나면서 점점 메모리가 쌓이고, 결국 성능 저하로 이어진다.

대표적으로:

  • 브라우저 점점 느려짐
  • 앱 반응 속도 저하
  • CPU 사용량 증가
  • 심하면 프로그램 강제 종료

같은 현상이 발생한다.

나도 예전에 특정 웹페이지를 하루 종일 켜둔 적이 있었는데, 나중에는 탭 하나만으로 메모리를 엄청 사용하고 있었다. 새로고침하니까 바로 정상으로 돌아왔는데, 그걸 보고 “아 내부에서 뭔가 계속 쌓이고 있었구나”라는 걸 체감했다.

그래서 실제 서비스에서는 단순히 기능이 동작하는 것만 중요한 게 아니라, 시간이 지나도 안정적으로 메모리를 관리할 수 있는지가 굉장히 중요하다.

결국 메모리 누수는 단순한 버그라기보다, 프로그램 구조와 관리 방식에서 발생하는 문제에 가깝다는 생각이 들었다.

한 줄로 정리하면 메모리 누수는 더 이상 필요하지 않은 객체가 참조를 유지한 채 계속 메모리에 남아 있는 현상이며, 시간이 지날수록 프로그램 성능을 점점 악화시키는 원인이 된다.