> For the complete documentation index, see [llms.txt](https://real-dev.gitbook.io/real-library/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://real-dev.gitbook.io/real-library/os_with_joonion/21-.-virtual-memory.md).

# 21강. Virtual Memory

#### 개요

* 어떤 프로그램의 크기가 가용 메모리 공간보다 크더라도 이를 실행할 수 있도록 하는 테크닉을 의미한다.
* 현대의 운영체제에서도 굉장히 유용한 테크닉으로 사용되고 있다.
* 실행되는 프로그램 파트는 메인 메모리에, 실행되지 않는 부분은 부 저장공간에 냅둔다.

<br>

#### Demand Paging

* 결국 2nd 메모리에서 실제 메모리에 페이지를 로딩하는 방식이 필요한데, 그럼 **로딩 될** 페이지에 대한 관리도 필요해진다.
* 따라서 이런 핸들링을 위해서 valid/invalid 비트를 관리하여 메모리에 로딩되어 있거나 세컨더리 메모리에 적재된 상태를 나타낼 수도 있다.
* Page fault → 아직 메모리에 적재되지 않은 상태에서 액세스가 발생하는 현상
  * 이 때 valid 비트를 확인하여 오류라면 프로세스를 종료하고, invalid 상태라면 메모리 프레임에 로드한다.
* Pure Demand Page: 요청이 없다면 메모리 로딩을 전혀 수행하지 않는 방식
  * 프로그램을 실행하는 시점에도 메인 메모리에 로드하지 않고, 무조건 페이지 폴트가 발생하야 페이지를 프레임에 로드한다.
  * 비효율적이다. 매번 페이지 로딩이 발생하면 성능상 좋을 수가 없겠지
* 참조 지역성: Pure Demand Paging 방식은 효율이 떨어지므로 참조되어지는 데이터와 근접한 페이지를 함께 로딩하는 방식으로 논리적으로 효율을 증명할 수는 없지만 실제로 효율이 좋은 경우가 있다.
* page fault가 발생하면 OS에 trap()을 걸고 `Page-out, page-in`을 수행한다. context switch가 발생한다는 뜻인데, 그럼 프로세스를 다시 실행될 때 똑같은 상태로 다시 실행되어야 한다. 다만 프로세스가 점유했던 프레임에 다시 배치될 가능성이 보장되지는 않는데, 그렇기에 페이지 테이블이 정교하게 관리되어야 한다.
* 또한 사용 가능한 프레임의 리스트을 관리해줘야 한다. 그럼 페이지 폴트가 발생했을 때 사용 가능한 프레임을 차례로 사용한다.

<br>

#### Demand Paging 성능

* 메모리 액세스 시간 (ma), page fault 발생 가능성 (p)
  * EAT = (1-p)\* ma+p \* (page fault time)
  * page fault time은 read page, 컨택스트 스위치 대기 큐, 스와핑, 트랩(interrupt) 등등 많은 작업이 발생하기 때문에 ma보다 훨씬 긴 시간이 발생한다.

<br>

#### Copy on Write

* fork()를 통해 복제된 프로세스들 사이에서 새로운 변수를 참조하는 등 새로운 쓰기 작업이 발생하기 전에 별도의 물리 메모리를 사용하지 않는 방식. 참조를 유지하고 변경에만 반응한다고 이해할 수 있을 것 같다.

<br>
