<aside> ❗
들어가기 앞서 Paging과 Segmetation을 살펴보기 전 메모리에 대한 기능적 정의가 필요
</aside>
이 상황에서 프로그램 용량이 메인 메모리보다 크면 어떤 일이 생길까?┌────────────────────────────ㅡㅡ┐
│ 메모리 전체 구조 │
├────────────────────────────ㅡㅡ┤
│ * 물리 메모리 (Physical) │
│ ├─ 실제 RAM 칩 │
│ └─ 디스크(Swap) 일부 사용 │
├────────────────────────────ㅡㅡ┤
│ * 논리 메모리 (Logical) │
│ ├─ 가상 메모리(Virtual Memory) │
│ │ ├─ 코드(Code) │
│ │ ├─ 데이터(Data) │
│ │ ├─ 힙(Heap) │
│ │ └─ 스택(Stack) │
└───────────────────────────ㅡㅡ─┘
물리 메모리 개념과 논리 메모리 개념을 분리한 것가상 주소를 사용
메모리 관리 장치(MMU)는 가상 주소를 이용해 실제 물리 메모리의 주소로 변환
하나의 프로세스가 메모리에 저장되는 논리적인 모습을 가상 메모리에 구현한 공간이며, 가상 주소는 해당 공간을 나타냄정리
----
가상 주소 공간
- 하나의 프로세스가 메모리 저장되는 "논리적 모습"
가상 주소
- 가상 주소 공간을 가르키는 주소
MMU
- 가상 주소를 사용하여 실제 물리 메모리의 주소로 변환
CPU
- 변환된 물리 주소를 이용해 RAM에 접근 -> 데이터를 읽거나 명령을 수행
동작 구조
---------
1. 페이지 테이블 등록 안 된 경우
CPU -> 가상 주소 0x1234 접근
↓
MMU -> 페이지 테이블 확인 -> 물리 주소 정보 없음 //페이지 테이블은 RAM에 존재
↓
Page Fault 발생
↓
운영체제(OS)가 디스크에서 해당 페이지를 읽어 RAM(ex. 0xA320)에 적재
↓
페이지 테이블 갱신 : [0x1234 -> 0xA3210]
↓
CPU 명령 재실행 -> 변환 성공
2. 페이지 테이블 등록된 경우
CPU -> 가상 주소 0x1234 등록
↓
MMU -> 페이지 테이블 조회 -> 물리 주소 0xA320 찾음
↓
즉시 RAM 접근 -> 데이터 읽기/쓰기 성공
--------------------------------------------------------------------
=>
"2번"이 동작이 되려면 1번의 "1번"이 동작이 되어서 "페이지 폴트 -> OS가 디스크에 페이지를 RAM으로 적재" 과정이 필요
메모리(RAM) 구조
---------------
┌────────────────────────────────────┐
│ 커널 영역 (Kernel Space) │ ← OS 관리, 사용자 접근 불가
│ ├─ 페이지 테이블(Page Tables) │
│ ├─ 커널 코드/데이터 구조 등 │
│ └─ 시스템 버퍼/캐시 등 │
├────────────────────────────────────┤
│ 사용자 영역 (User Space) │ ← 프로세스별로 독립된 가상 메모리 공간
│ ├─ 코드(Code/Text) │
│ ├─ 데이터(Data) │
│ ├─ 힙(Heap) │
│ ├─ 스택(Stack) │
└────────────────────────────────────┘
+
추가 내용
---------
새로운 프로레스가 생성되면 OS는 그 프로세스용으로 가상 주소 공간만 논리적으로 할당
이 시점에는 RAM에는 실제 데이터가 거의 없음
그래서 CPU가 가상 주소를 읽으면 RAM에 물리 메모리가 매핑되지 않아 PAGE FAULT가 발생하고 이 과정에서 가상 주소 <-> 물리 주소를 할당해주는게 MMU임
그리고 만약 RAM이 꽉 차면 Swapping 과정을 진행하는데 이는 다음 페이지에 설명
물리 메모리의 한계 극복
- 실제 RAM 용량보다 휠씬 큰 프로그램을 실행할 수 있음
멀티태스킹 효율 증대
- 프로그램의 모든 부분을 RAM에 올리는 대신, "지금 필요한 부분(핵심)"만 올리고 나머지는
디스크(Swap 영역)에 보관. 이로써 한정된 RAM으로 더 많은 프로세스를 동시에 실행 가능
메모리 보호
- 각 프로세스는 자신만의 가상 주소 공간에 완벽히 격리
- 이로써 한 프로세스의 오류가 다른 프로세스의 메모리를 침범하는 것을 원천적으로 차단
호율적인 프로세스 생성
- 새로운 프로세스를 만들 때, 부모 프로세스의 메모리 전체를 복사하는 대신 "페이지 테이블"
이라는 주소록만 복사, 이로써 CoW하여 프로세스 생성 속도를 크게 향상
+
여기서 CoW(Copy-on-Write) 동작
1. 프로세스 A와 B가 "같은 가장주소 범위"를 갖더라도, 실제로 그 VA가 가리키는
물리 프레임(PFN(Page Frame Number))임.
2. CoW는 처음엔 둘이 같은 PFN을 가리키게 해서 공유하고
3. 누가 쓰려고 하면 PFN의 내용을 새 프레임으로 복사.