콘텐츠로 건너뛰기

RAM이 16GB인데 100GB 메모리를 사용할 수 있다고?

컴퓨터의 메모리를 확인하다 보면 이상한 숫자를 발견할 때가 있다.

분명 내 컴퓨터에 장착된 RAM은 16GB인데, 운영체제가 표시하는 프로세스의 가상 메모리 크기는 그보다 훨씬 클 수 있다.

심지어 하나의 프로그램이 수십 GB의 가상 주소 공간을 사용하고 있다고 표시되기도 한다.

여기서 의문이 생긴다.

물리적인 RAM은 16GB뿐인데 어떻게 프로그램은 그보다 큰 메모리 공간을 사용할 수 있을까?

이를 이해하려면 운영체제가 메모리를 관리하는 방식, 특히 가상 메모리(Virtual Memory)라는 개념을 알아야 한다.

1. 프로그램이 사용하는 주소는 실제 RAM 주소가 아니다

일반적으로 프로그램은 메모리에 접근할 때 특정 주소를 사용한다.

int number = 10;

printf("%p\n", (void *)&number);

위 코드를 실행하면 number 변수의 주소를 확인할 수 있다.

그런데 이 주소는 실제 RAM 칩의 물리적 위치를 그대로 나타내는 주소일까?

일반적인 현대 운영체제의 사용자 프로세스에서는 그렇지 않다.

프로그램이 사용하는 주소는 **가상 주소(Virtual Address)**다.

운영체제와 하드웨어는 이 가상 주소를 실제 메모리의 물리 주소로 변환하여 사용한다.

프로그램
   |
   ▼
가상 주소
   |
   ▼
MMU + 페이지 테이블
   |
   ▼
물리 주소
   |
   ▼
RAM

여기서 MMU(Memory Management Unit)는 가상 주소를 물리 주소로 변환하는 데 사용되는 하드웨어다.

페이지 테이블(Page Table)은 이러한 주소 변환에 필요한 정보를 관리하는 자료구조다.

운영체제는 프로세스마다 독립적인 가상 주소 공간을 제공할 수 있다.

따라서 두 프로세스가 동일한 가상 주소를 사용하더라도 반드시 같은 물리 메모리를 가리키는 것은 아니다.

이 덕분에 프로세스는 서로의 메모리를 함부로 침범하지 않고 독립적인 주소 공간에서 실행될 수 있다.

2. 가상 메모리는 왜 필요할까?

가상 메모리의 중요한 목적 중 하나는 프로그램이 물리 메모리의 배치를 직접 관리하지 않아도 되도록 만드는 것이다.

과거처럼 프로그램이 물리적인 메모리 위치를 직접 고려해야 한다면 여러 프로그램을 동시에 실행하고 보호하는 일이 복잡해질 것이다.

가상 메모리 시스템에서는 프로그램이 연속된 주소 공간을 사용하는 것처럼 보이더라도 실제 물리 메모리는 여러 위치에 나누어 배치될 수 있다.

이때 메모리를 일정한 크기의 단위로 나누어 관리하는 방식이 페이징(Paging)이다.

가상 주소 공간은 페이지(Page) 단위로 나뉘고, 물리 메모리는 페이지 프레임(Page Frame) 단위로 관리된다.

가상 주소 공간           물리 메모리

Page 0  ───────────────→ Frame 5
Page 1  ───────────────→ Frame 2
Page 2  ───────────────→ Frame 8
Page 3  ───────────────→ Frame 1

가상 주소상에서는 연속된 페이지라도 실제 물리 메모리에서는 서로 떨어진 위치에 존재할 수 있다.

페이지 테이블은 이러한 매핑 정보를 제공한다.

그런데 매번 페이지 테이블을 확인해야 한다면 메모리에 접근할 때 추가 비용이 발생하지 않을까?

이를 줄이기 위해 CPU에는 TLB(Translation Lookaside Buffer)라는 주소 변환 캐시가 존재한다.

TLB에 필요한 변환 정보가 있다면 페이지 테이블을 매번 따라가지 않아도 된다.

즉, 가상 메모리는 단순히 RAM 부족을 해결하기 위한 기술이 아니라, 메모리 보호와 효율적인 주소 공간 관리에도 중요한 역할을 한다.

3. RAM에 없는 메모리는 어떻게 사용할까?

여기서 등장하는 개념이 Demand Paging이다.

프로그램이 가상 주소 공간을 확보했다고 해서 그 전체 공간을 즉시 물리 RAM에 할당해야 하는 것은 아니다.

운영체제는 실제로 필요한 페이지를 그때그때 물리 메모리에 연결할 수 있다.

가령 프로그램이 10GB의 가상 메모리 공간을 확보했다고 가정하자.

하지만 실제로 접근한 영역이 100MB 정도라면 물리 메모리 사용량은 가상 주소 공간의 크기보다 훨씬 작을 수 있다.

물론 운영체제의 메모리 할당 정책과 매핑 방식에 따라 실제 동작은 달라진다.

이제 프로그램이 접근하려는 가상 페이지가 현재 물리 메모리에 매핑되어 있지 않다면 어떻게 될까?

이때 Page Fault가 발생할 수 있다.

Page Fault는 CPU가 접근하려는 가상 페이지에 대해 현재 필요한 매핑이 존재하지 않거나, 접근 권한 등의 조건을 만족하지 못할 때 발생하는 예외다.

운영체제는 원인을 확인하고 정상적으로 처리 가능한 경우 필요한 페이지를 할당하거나 저장 장치에서 불러오는 등의 작업을 수행한다.

여기서 알아둘 점은 Page Fault가 발생했다고 해서 반드시 프로그램 오류인 것은 아니라는 사실이다.

정상적인 Demand Paging 과정에서도 Page Fault는 발생할 수 있다.

반면 유효하지 않은 주소를 접근했다면 프로세스에 오류가 발생할 수 있다.

4. RAM이 부족하면 SSD를 사용하는 걸까?

물리 RAM이 부족해지면 운영체제는 메모리에 있는 페이지 중 일부를 다른 곳으로 이동시키는 전략을 사용할 수 있다.

대표적인 방식이 Swap이다.

Swap은 필요에 따라 메모리 페이지의 내용을 보조 저장 장치에 보관하고, 나중에 다시 필요해지면 읽어오는 방식이다.

실행 중인 프로그램
       |
       ▼
   가상 메모리
       |
       ├── 현재 RAM에 있는 페이지
       |
       └── Swap 영역에 있는 페이지
                      |
                      ▼
                 SSD / 저장장치

그러나 SSD는 일반적으로 RAM보다 접근 지연이 크다.

따라서 자주 사용하는 페이지가 RAM에 없어서 계속 저장 장치에서 읽어와야 한다면 성능이 크게 떨어질 수 있다.

이처럼 메모리가 부족하여 페이지 교체와 입출력에 과도한 시간을 사용하는 상황을 스래싱(Thrashing)이라고 한다.

프로그램이 일을 하는 시간보다 메모리 페이지를 교체하는 데 소비하는 시간이 지나치게 많아지는 것이다.

다만 macOS와 같은 현대 운영체제는 Swap 외에도 메모리 압축과 다양한 메모리 회수 기술을 사용한다.

따라서 RAM이 부족하다고 반드시 모든 페이지를 SSD로 옮기는 것은 아니다.

5. 그렇다면 16GB RAM으로 100GB를 사용할 수 있을까?

처음 질문으로 돌아가 보자.

RAM이 16GB인데 프로그램이 100GB의 메모리를 사용한다고 표시된다면, 그 숫자가 무엇을 의미하는지 먼저 확인해야 한다.

100GB가 가상 주소 공간의 크기라면 충분히 가능한 상황이다.

하지만 실제로 100GB의 데이터를 메모리에 적재하고 모두 활발하게 접근하는 상황은 다르다.

물리 RAM과 Swap 공간, 운영체제 정책 등의 한계가 존재하고, 심각한 성능 저하나 메모리 부족 오류가 발생할 수 있다.

즉, 가상 메모리는 물리 RAM을 무한대로 늘려주는 마법 같은 기술이 아니다.

가상 주소 공간과 실제 물리 메모리 사용량을 분리하고 효율적으로 관리하는 기술이다.

macOS에서 직접 확인해 보자

macOS에서는 다음 명령으로 메모리 통계를 확인할 수 있다.

vm_stat

또는 현재 셸 프로세스의 가상 메모리와 상주 메모리 정보를 확인할 수 있다.

ps -o pid,vsz,rss,comm -p $$

여기서 일반적으로 VSZ는 가상 메모리 크기를, RSS는 현재 물리 메모리에 상주하는 메모리 크기를 나타낸다.

두 값이 항상 같지는 않다.

활성 상태 보기(Activity Monitor)의 메모리 탭에서도 메모리 압력, Swap 사용량 등을 확인할 수 있다.

이러한 지표는 단순히 RAM 사용률 하나만 보는 것보다 시스템 상태를 이해하는 데 도움이 된다.

6. 메모리 크기를 볼 때 무엇을 봐야 할까?

가상 메모리를 이해하고 나면 중요한 사실을 알게 된다.

프로그램이 확보한 주소 공간의 크기와 실제 RAM 사용량은 서로 다른 개념이라는 것이다.

메모리 문제를 분석할 때는 가상 메모리 크기만 보는 것이 아니라, 실제 상주 메모리와 메모리 압력, Swap 사용량, 페이지 폴트 등의 지표를 함께 살펴볼 필요가 있다.

개발자가 메모리 누수나 OOM 문제를 조사할 때도 마찬가지다.

운영체제가 메모리를 얼마나 가지고 있는지보다 더 중요한 질문은, 프로그램이 실제로 어떤 메모리를 사용하고 있으며 운영체제가 이를 어떻게 관리하고 있는가다.

생각해 볼 문제

Q1. 서로 다른 프로세스가 동일한 가상 주소를 사용하는 것이 가능한 이유는 무엇일까?

Q2. Page Fault는 무조건 프로그램 오류를 의미할까?

Q3. RAM 사용률이 높지만 Swap 사용량과 메모리 압력이 낮다면 반드시 메모리를 추가해야 할까?

참고 자료

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

Exit mobile version