프로그래밍공부(Programming Study)/CS-운영체제(OS)

free를 했는데 왜 RSS는 줄어들지 않을까

Chann._.y 2026. 4. 4.
728x90

앞 글에서 malloc은 대부분 빠르지만,
특정 순간에는 느려질 수 있다고 정리했다.

그런데 실제로 메모리 관련해서 더 자주 마주치는 문제는 따로 있다.

free를 했는데 메모리 사용량이 그대로다

처음 보면 꽤 당황스럽다.

free(p);

코드상으로는 분명히 메모리를 해제했다.
그런데 top이나 htop 같은 걸 보면 RSS가 그대로다.

이건 버그가 아니라,
메모리가 그렇게 동작하도록 설계되어 있기 때문이다.


free는 “메모리 반환”이 아니다

여기서 한 번 개념을 다시 잡고 가야 한다.

우리가 흔히 생각하는 건 이거다.

malloc → OS에서 가져옴
free → OS에 돌려줌

하지만 실제로는 다르다.

free는 OS에 메모리를 돌려주는 게 아니라,
malloc에게 “이거 다시 써도 된다”고 알려주는 동작이다


즉, 내부에서는 이렇게 된다.

malloc → 메모리 사용
free   → allocator 내부로 반환

OS 입장에서는 아무 일도 안 일어난다.


그래서 RSS는 그대로다

여기서 RSS를 보면 이해가 된다.

RSS = 실제 물리 메모리에 올라와 있는 양


free 이후 상태를 보면 이렇다.

  • 메모리는 사용 안 함
  • 하지만 프로세스에 그대로 붙어 있음
  • 물리 메모리에도 그대로 존재

즉,

“안 쓰고 있지만, 들고는 있는 상태”

라서 RSS가 줄어들지 않는다.


그럼 왜 바로 OS에 안 돌려줄까

이건 성능 때문에 그렇다.


만약 free가 항상 OS에 반환한다면

malloc → system call
free   → system call

이렇게 된다.

문제는 명확하다.

  • 시스템 콜 비용 큼
  • 커널 진입 발생
  • 성능 크게 저하

그래서 allocator는 이렇게 선택한다.

“일단 들고 있다가, 나중에 재사용하자”


이게 바로 메모리 풀 전략이다.


실제로는 대부분 재사용된다

이 구조 덕분에 이런 일이 가능하다.

p = malloc(100);
free(p);
q = malloc(100);

이 경우 q는:

새로 OS에서 받은 게 아니라, 방금 free된 걸 재사용할 가능성이 높다


그래서 malloc/free가 빠르다.


그럼 언제 RSS가 줄어들까

완전히 줄어들지 않는 건 아니다.


1. mmap으로 할당된 경우

큰 메모리는 mmap으로 할당되는 경우가 많다.

이 경우 free하면:

free → munmap → OS 반환

👉 이건 바로 RSS 감소로 이어진다.


2. 힙의 끝 부분인 경우

sbrk 기반 메모리는
힙의 끝(top chunk)일 때만 OS에 반환 가능하다.


즉:

  • 중간에 있는 free 메모리 → 반환 불가
  • 끝에 있는 메모리 → 조건 맞으면 반환 가능

그래서 대부분의 경우는:

그대로 남는다


여기서 더 헷갈리는 포인트 하나

RSS가 증가했다고 해서 무조건 문제가 있는 건 아니다.


RSS는 두 가지가 섞여 있다

  • anonymous memory (malloc, stack 등)
  • page cache (파일 캐시)

이 둘은 완전히 다른 성격이다.


anonymous memory

  • malloc으로 만든 메모리
  • 프로세스 전용
  • 우리가 흔히 생각하는 “프로그램 메모리”

page cache

  • 파일을 읽을 때 생김
  • 커널이 관리
  • 여러 프로세스가 공유 가능

👉 중요한 포인트

RSS에는 이 둘이 같이 들어간다


그래서 이런 상황이 가능하다.

  • RSS 증가
  • 하지만 실제로는 page cache 증가

즉,

메모리 누수가 아닐 수도 있다


그래서 분석할 때는 이렇게 봐야 한다

단순히 RSS만 보면 안 된다.


꼭 같이 봐야 하는 것

  • RSS
  • anon memory
  • file-backed memory (page cache)

그리고 항상 이 질문을 해야 한다.

이 메모리는 누가 쓰고 있는 건가?


  • malloc인가?
  • 파일 캐시인가?
  • mmap인가?

여기까지 정리하면

이제 왜 이런 현상이 생기는지 이해된다.


free했는데 메모리가 안 줄어드는 이유

  • OS에 반환이 아니라
  • allocator 내부로 돌아가기 때문

RSS가 유지되는 이유

  • 물리 메모리에 그대로 남아 있기 때문

실제 문제인지 판단하는 기준

  • anon인지
  • page cache인지

다음으로 이어지는 질문

여기까지 보면 이런 생각이 든다.

그럼 실제로 메모리를 어떻게 분석해야 할까?
/proc/smaps 같은 건 어떻게 읽어야 할까?

이건 단순 개념이 아니라
실제 운영 환경에서 쓰는 내용이라 다음 글에서 다루는 게 자연스럽다.


한 줄 정리

free는 메모리를 OS에 반환하는 동작이 아니라 allocator 내부로 되돌리는 것이기 때문에, 대부분의 경우 RSS는 줄어들지 않는다.

728x90

댓글