최근 수정 시각 : 2024-11-03 16:29:27

메모리 누수

1. 개요2. 상세

1. 개요

메모리 누수(Memory leak)는 응용 프로그램에서 데이터를 메모리에 올렸다가, 이것이 쓸모없어지는 시점에서 적절하게 제거되지 않는 것을 '누수'에 빗댄 말이다. 영어를 그대로 읽은 '메모리 릭'이라는 표현으로도 적지 않게 쓰인다.

2. 상세

메모리 누수가 지속되면 메모리 자원의 반환이 원활히 되지 않아 메모리 부족으로 이런저런 버그가 생기거나, 더 나아가 프로그램이 응답하지 않거나 아예 강제로 종료된다.[1][2] 쓰레기 수집 기능은 이를 방지하기 위한 기능이지만 완전하지는 않다. 발적화의 원흉 중 하나.

메모리에 데이터가 남아 있어도 그 상황을 운영체제가 통제하고 있다면 데이터 누수라고 하긴 어렵다. Windows Vista 이후의 운영체제 및 안드로이드에선 옛날만큼 메모리 공간이 빡빡하지 않다는 것을 감안하여 사용자가 종료시킨 프로그램을 일부러 메모리 상에 남겨두어 나중에 사용자가 다시 찾았을 때 더 빠르게 응답할 수 있도록 설정되어 있다. 여기서 한술 더 떠서 자주 사용하는 프로그램이라면 부팅 이후로 아직 실행된 적이 없더라도, 운영체제가 먼저 메모리에 띄워놓기까지 한다.[3] 하지만 이런 경우들은 운영체제가 현재 상황을 알면서 일부러 놔둔 것이므로 사용자가 다른 작업을 하느라 메모리 공간이 부족해지면 운영체제가 알아서 메모리를 정리해준다.[4] 다만 윈도우 10 1703부터는 저 정리의 반응속도가 느려서 고사양 게임에서 마이크로스터터링을 일으키는 문제가 있었다.[5] 게임 자체 최적화 문제와 맞물려서 큰 논란이 된 가장 대표적인 사례가 바로 PUBG (톰 클랜시의 디비전 2의 사례를 포함한 설명 #) 그리고 윈도 모바일은 메모리가 빡빡한데도 기본 설정으론 이렇게 동작해서 문제였다.[6]

한편 FORTRAN이나 BASIC, C 등의 프로그래밍 언어는 쓰레기 수집을 지원하지 않는다. 애초에 이 언어들은 프로그래머를 믿고 컴파일러의 개입을 최소화하는 게 특징이다. 특히 C/C++은 포인터와 동적 할당이 기본 테크닉이라 더 심하다. C++의 경우, C++11 이후 추가된 스마트 포인터에서 참조 횟수 카운팅 쓰레기 수집을 지원하지만, 어디까지나 선택사항이고 성능 하락을 막기 위해 직접 관리해야 하는 부분도 적지 않다. 이에 따라 FORTRAN, BASIC, C, C++ 전공의 프로그래머는 오늘도 메모리와의 전쟁을 치르고 있다.

[1] 일반적으로는 메모리가 계속 불어나다가 멈추지만 가끔 램 여유가 충분히 된다면 한계까지 잡아먹는 버그로 유명한 프로그램들도 있었다.[2] 32비트 윈도우에선 프로그램당 최대 점유할 수 있는 메모리가 2G라 메모리 누수가 발생할 경우 64비트보다 빨리 터진다.[3] 이러한 메커니즘을 윈도우에선 superfetch, 리눅스에선 readahead라고 부른다. 하지만 메모리에 데이터를 미리 올리기 위해 때론 렉을 유발하기도 한다. 윈도우에서 아무 작업도 안 하고 있는데 저장장치 혼자 바쁘다면 superfetch 때문인 경우가 많다.[4] 그래서 최근 실행 목록에서 모두닫기를 누르지 말라고 하는 이유다.[5] https://quasarzone.com/bbs/qb_tip/views/12664[6] 사실 초기 Android도 메모리를 한번씩 정리해줘야 했다.

파일:CC-white.svg 이 문서의 내용 중 전체 또는 일부는 문서의 r45에서 가져왔습니다. 이전 역사 보러 가기
파일:CC-white.svg 이 문서의 내용 중 전체 또는 일부는 다른 문서에서 가져왔습니다.
[ 펼치기 · 접기 ]
문서의 r45 (이전 역사)
문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)