[CS] Demand-Zero Memory

Demand-Zero Memory란?

Demand-Zero Memory란 "처음 접근할 때 0으로 초기화된 메모리"를 말한다.

정의

  • Demand-zero memory프로그램이 요청하지만 아직 실제로 물리 메모리가 할당되지 않은 페이지이다.
  • 이 메모리 페이지에 처음 접근하는 순간 운영체제가 실제 물리 메모리를 할당해 주며, 그 메모리의 모든 내용은 0으로 초기화된다.
즉, 프로그램이 메모리를 요청할 때 미리 0을 써놓지 않고, 실제로 쓸 때 0으로 된 메모리를 제공하는 것이다.

왜 'Demand' + 'Zero'인가?

  • Demand: "필요할 때" (접근할 때) 물리 메모리를 할당함
  • Zero: "초기값은 모두 0" 으로 채워진 메모리를 줌

예시 1.

int *arr = calloc(100, sizeof(int));

 

 

  • calloc은 0으로 초기화된 100개의 int 배열을 요청한다.
  • 운영체제는 실제로는 바로 400바이트를 물리적으로 메모리에 할당하지 않는다.
  • 대신, 페이지 테이블에 'demand-zero page'라고 표시해 놓는다.
  • 프로그램이 arr[0], arr[1] 등에 실제 접근하려 하면, 그 순간 Page Fault가 발생하고
  • 운영체제가 0으로 초기화된 물리 메모리 페이지를 만들어서 매핑해 준다.

예시 2.

1. 프로그램이 메모리를 요청할 때

int big_array[1000000];
  • 이 big_array는 굉장히 큰 메모리 공간을 필요로 한다.
  • 컴파일러는 이걸 .bss 섹션에 놓거나, 스택/힙에 놓는다.
  • 이때 운영체제는 실제 물리 메모리를 바로 할당하지 않는다.
  • 대신 페이지 테이블(Page Table)에 "아직 없음"이라고 표시하거나,
    특별히 "Demand-Zero 페이지" 타입으로 표시한다.

이렇게 하면 프로그램 입장에서는 big_array가 준비되어 있는 것처럼 보인다.

2. 메모리에 접근할 때 (Page Fault 발생)

프로그램이 처음으로 big_array[0] = 1; 처럼 쓰기를 시도하면:

  • CPU는 메모리에 접근하려고 한다.
  • 그런데 페이지 테이블을 보니, 아직 물리 메모리 매핑이 안 되어 있지 않았다.
  • 그러면 CPU가 Page Fault 예외(Page Fault Exception)를 발생시킨다.

운영체제(OS)는 이 Page Fault를 잡아 처리한다.

3. 운영체제의 Page Fault 처리 과정

운영체제는 다음 순서로 처리한다:

  1. Fault가 발생한 주소를 확인한다.
  2. 페이지 테이블을 보고, 이 Fault가 Demand-zero 페이지에 대한 것임을 안다.
  3. 새로운 물리 메모리 페이지 하나를 할당한다.
  4. 그 페이지를 모두 0으로 초기화한다. (보안을 위해 무조건 0으로 설정한다.)
  5. 이 새 페이지를 가상 주소에 매핑한다.
  6. 페이지 테이블을 업데이트한다.
    • 페이지의 존재(bit set)
    • 읽기/쓰기 권한(bit set)
  7. 프로그램이 다시 정상적으로 해당 메모리에 접근할 수 있도록 한다.

결국 프로그램은 아무것도 모르는 상태로 big_array[0] = 1 같은 코드를 수행하게 된다.

4. 메모리 초기화가 꼭 필요한 이유

  • 보안상 필요하다.
    (만약 초기화를 안 하면, 다른 프로세스가 쓰던 메모리 내용을 읽어버릴 수도 있다.)
  • 따라서 OS는 항상 새로 할당된 demand-zero 메모리를 "0으로 초기화" 하고, 사용자 프로그램에 제공한다.

Demand-Zero vs Copy-On-Write

구부 Demand-Zero Copy-On-Write (COW)
발생 조건 처음 메모리 접근할 때 (아직 물리 메모리 없음) 공유된 페이지를 수정하려고 할 때 (다른 프로세스와 공유 중)
초기 상태 "메모리를 요청했지만, 실제로 0으로 초기화된 물리 페이지는 아직 없음" "다른 프로세스와 물리 페이지를 공유 중"
Fault 종류 Demand-Zero Page Fault Copy-On-Write Page Fault
OS 대응 새 물리 페이지를 할당하고 0으로 초기화 새 물리 페이지를 할당하고 기존 데이터를 복사
사용 예시 calloc(), BSS 섹션, MAP_ANONYMOUS fork() 이후 부모-자식 프로세스 메모리 분리

1. Demand-Zero: "아예 메모리가 없던 상태"

  • 메모리 요청했지만 물리 메모리 할당이 미뤄진 상태.
  • 접근할 때 0으로 초기화된 페이지를 새로 만들어서 제공.
  • 특징: 새로 할당 + 0으로 초기화
int *arr = calloc(1000, sizeof(int));

 

  • 여기서는 메모리를 쓰기 전까지 진짜 물리 메모리가 없음.
  • 쓰려고 할 때 Page Fault → OS가 0으로 초기화된 페이지를 연결해줌

 

2. Copy-On-Write: "공유된 메모리를 복사할 때"

  • 원래 물리 메모리가 존재하고, 여러 프로세스가 같은 물리 메모리를 공유하고 있다.
  • 누군가가 이 공유 메모리를 수정하려고 하면 Page Fault 발생.
  • OS는 수정하려는 프로세스만 새로운 복사본을 만들고, 기존 데이터 복사 후 수정하게 한다.
  • 특징: 복사 + 수정 (읽기만 하면 복사 안 함)
pid_t pid = fork();

 

 

  • fork() 호출하면 부모 프로세스의 메모리를 자식이 그대로 공유한다.
  • 둘 다 같은 물리 페이지를 읽기는 자유롭게 함.
  • 하지만 자식이나 부모가 수정(write) 하려고 하면
    • COW Page Fault
    • OS가 새 페이지를 복사해 주고, 그 뒤 수정하게 한다.