메모리 누수

컴퓨터과학·AI
한 줄 정의: 프로그램이 더 이상 쓰지 않는 메모리 공간을 계속 붙잡고 있어서, 시간이 지날수록 사용 가능한 메모리가 조금씩 줄어드는 현상입니다.

쉽게 풀면

도서관에서 책을 빌렸다가 다 읽고도 반납하지 않는 상황을 떠올려 보세요. 한두 번은 괜찮지만, 반납하지 않는 사람이 계속 쌓이면 결국 서가에 빌릴 수 있는 책이 하나도 남지 않게 됩니다. 프로그램도 마찬가지로 필요할 때 메모리(컴퓨터의 작업 공간)를 "빌려" 쓰고, 다 쓰면 "반납"해야 합니다. 그런데 코드에 실수가 있어서 다 쓴 메모리를 반납하지 않고 계속 붙잡고 있으면, 프로그램을 오래 켜둘수록 남은 메모리가 점점 줄어들다가 결국 느려지거나 멈추게 됩니다. 이것이 메모리 누수입니다.

왜 중요한가

메모리 누수는 시스템의 안정성과 직결되는 문제이기 때문에 소프트웨어 공학, 시스템 프로그래밍, 임베디드 시스템 연구에서 성능 평가의 중요한 항목으로 다뤄집니다. 특히 서버처럼 오랜 시간 끊김 없이 실행되어야 하는 시스템에서는 작은 누수도 시간이 누적되면 서비스 중단으로 이어질 수 있어, 새로운 프로그래밍 언어나 프레임워크를 제안하는 논문에서는 메모리 안전성을 얼마나 잘 보장하는지를 성능 지표와 함께 검증하는 경우가 많습니다.

논문에서는 이렇게 쓰입니다

"장시간 구동 실험에서 프로토타입 시스템에 메모리 누수가 발견되어, 24시간 이상 연속 실행 시 응답 지연이 점진적으로 증가하는 것을 확인하였다."

이 문장은 "시스템을 오래 켜두고 실험했더니 다 쓴 메모리가 제대로 반납되지 않아서, 시간이 지날수록 처리 속도가 느려지는 문제를 발견했다"는 뜻입니다.

"제안된 메모리 안전 언어로 재작성한 모듈에서는 동일한 워크로드 실행 시 기존 구현 대비 메모리 누수 발생 빈도가 유의하게 감소하였다."

이 문장은 메모리 관리를 더 엄격하게 강제하는 프로그래밍 언어로 다시 작성했더니, 같은 조건에서 실행해도 메모리 누수가 훨씬 덜 발생했다는 뜻입니다.

"모바일 애플리케이션의 정적 분석 도구는 순환 참조로 인한 잠재적 메모리 누수 지점을 코드 실행 없이 탐지할 수 있었다."

이 문장은 프로그램을 직접 실행하지 않고도 코드만 분석해서, 서로가 서로를 참조하는 구조 때문에 생길 수 있는 메모리 누수 위치를 미리 찾아낼 수 있었다는 뜻입니다.

조금 더 깊게 보면

메모리 누수를 찾아낼 때는 흔히 프로그램 실행 중 메모리 사용량 변화를 시간에 따라 기록하는 프로파일링 도구를 사용하며, 대표적으로 힙(heap) 메모리의 할당과 해제 내역을 추적하는 방식이 있습니다. 가비지 컬렉션을 쓰는 언어에서는 더 이상 쓰이지 않아야 할 객체를 다른 객체가 참조를 놓지 않아 발생하는 경우가 많은데, 두 객체가 서로를 참조하는 순환 참조(circular reference)가 대표적인 원인 중 하나로 꼽힙니다. C나 C++처럼 메모리를 직접 관리하는 언어에서는 할당한 메모리를 해제하는 코드를 누락하는 실수가 흔한 원인입니다.

주의할 점

메모리 누수는 가비지 컬렉션을 지원하는 언어에서도 발생할 수 있습니다. 예를 들어 더 이상 필요 없는 객체를 다른 객체가 계속 참조하고 있으면, 가비지 컬렉터는 이를 "아직 쓰는 중"이라고 착각해 회수하지 않습니다. 즉 가비지 컬렉션이 있다고 메모리 누수가 완전히 사라지는 것은 아니며, 프로그램 실행 중 메모리 사용량을 주기적으로 관찰하는 것이 예방에 중요합니다.

관련 용어