본문 바로가기
OS(운영체제)

가상메모리 (Virtual memory)

by 걸어가는 신사 2021. 12. 9.

* 들어가기 전에

  • 메모리의 여러 관리 전략은 모두 다중 프로그래밍을 실현하기 위해 메모리에 많은 프로세스를 동시에 유지하는 것
  • 지금까지는 접근 방식은 프로세스 전체가 실행되기 전에 메모리로 올라와야 한다는 것을 전제
  • 가상 메모리 라는 것은 프로세스 전체가 메모리 내에 올라오지 않더라도 실행이 가능하도록 하는 기법

 

1. 가상메모리 (Vitual Memory)

실제 메모리와는 다르게 메모리를 추상화하여 사용자에게 더 큰 메모리로 보이게 한다.
  • 프로세스 전체가 메모리 내에 올라오지 않더라도 실행이 가능하도록 하는 기법
  • 실제의 물리 메모리 개념과 개발자의 논리 메모리 개념을 분리한 것이다.
  • 작은 메모리를 가지고도 얼마든지 큰 가상 주소 공간을 프로그래머에게 제공할 수 있다.

(1) 가상메모리 이점

  • 프로그램은 물리 메모리 크기에 의해 더 이상 제약받지 않는다.
    • 사용자는 매우 큰 가상 주소공간을 메모리 공간이라고 생각한다.
  • 각 프로그램이 더 작은 메모리를 차지하므로 더 많은 프로그램을 동시에 수행할 수 있다.
    • 응답 시간은 늘어나지 않으면서도 CPU 이용률(utilization)과 처리율(throughput)이 높아진다.
  • 프로그램을 메모리에 올리고 스왑(swap)하는데 필요한 I/O 횟수가 줄어들어 빨리 실행된다.

(2) 가상 주소 공간 (Virtual-address Space)

프로세스가 메모리에 저장되는 논리적인 공간
  • 특정 논리 주소는 보통 0번지에 시작하여 연속적인 공간을 차지한다.
    • 물리적 주소로 바뀌며서 비연속적 공간으로 바뀐다.
  • heap이나 stack은 동적으로 변하는 공간이기 때문에 이런 공간을 성긴(Sparse) 주소 공간이라고 한다.

(3) 공유 페이지

  • 가상 메모리는 페이지 공유를 통해 파일이나 메모리가 둘 또는 그 이상의 프로세스들에 의해 공유되는 것을 가능하게 한다.
  • 논리 주소를 물리적 주소로 Mapping 하는 과정에서 같은 물리적 주소를 Mapping 함으로써 공유된다.

 

2. 요구 페이징 (Demand Paging)

필요한 페이지만 보조 저장장치에서 메모리로 적재한다.
  • 가상 메모리 시스템에서 일반적으로 사용된다.
  • 요구 페이징 가상 메모리를 사용하면 프로그램 실행 중 필요할 때만 페이지가 적재된다.
  • 요구 페이징 시스템은 프로세스가 스와핑을 사용하는 페이징 시스템과 유사하다.
  • 필요한 프로그램의 일부만 적재하여 메모리가 더 효율적으로 사용된다.

  • process는 page 8개가 모두 memory에 올라와 있다고 생각한다. (virtual memory)
  • 실제 memory에는 3개의 page만 올라와 있다. (physical memory)

(1) 유효-무효 비트 (Valid-Invalid Bit)

  • 페이지 테이블에 들어있다.
  • v => 유효(valid)하다고  설정되면 해당 페이지가 메모리에 있다는 의미
  • i => 무효(invalid)하다고 설정되면 해당 페이지가 메모리에 없다는 의미
    • 페이지 폴트가 발생

(2) 페이지 폴트 (Page Fault)

프로세스가 메모리에 올라와 있지 않은 페이지에 접근 시 발생. (유효-무효 비트가 i인 경우)
  • 페이지 테이블 항목이 무효로 설정되어 있으면 페이지 폴트 트랩(page-fault trap) 발생
  • 페이지 폴트가 발생하는 두 가지 경우 (Valid-Invalid Bit 가 i 인 경우)
    • 가상 주소 공간상에 정의되지 않은 경우, Invalid reference (접근 불가능한 공간)
    • 유효하지만 disk에 존재하는 경우, Just not in memory (memory에 존재 X) 
  • 순수 요구 페이징(pure demand paging)
    • 어떤 페이지가 필요해지기 전까지 페이지를 메모리로 적재하지 않는 방법
    • 메모리에 페이지가 하나도 안 올라와 있는 상태에서 프로세스 실행 시작
  • 참조 지역성(locality of reference)
    • 프로그램의 어느 한 특정 작은 부분만 한동안 집중적으로 참조한다.
    • 한 명령어에도 여러 개의 페이지 폴트 발생 확률은 매우 작다.
    • 그러므로 요구 페이징은 만족할 만한 성능을 보인다.

(3) 페이지 폴트 처리 과정

  • 프로세스에 대한 내부 테이블(internal table)을 검사해서 그 메모리 참조(reference)가 유효 또는 무효인지 알아낸다.
  • 만약 무효한 페이지에 대한 참조라면 그 프로세스는 중단된다. 만약 유효한 참조인데 페이지가 아직 메모리에 올라오지 않았다면, 그것을 disk로부터 가져온다.
  • 빈 공간, 즉 가용 프레임(free frame)을 찾는다.
  • disk에 새로 할당된 프레임에 해당 페이지를 읽어 온다.
  • disk가 읽기가 끝나면, 이 페이지가 유지하고 있는 내부 테이블을 수정
    • validation을 V로 설정한다.
  • 트랩에 의해 중단되었던 명령어를 다시 수행

 

3. 요구 페이징의 성능 (Performance of Demand Paging)

  • 요구 페이징은 컴퓨터 시스템의 성능에 큰 영향을 줄 수 있다.

(1) 페이지 폴트 처리 시간의 3가지 주요 작업 요소

  • 인터럽트의 처리
  • 페이지 읽기
  • 프로세스 재시작

(2) 실질 접근 시간 (Effective Access Time, EAT)

  • 페이지 폴트의 확률 p (0<= p <=1)
  • EAT = (1-p) * memory access + p * (page fault overhead + swap page out + swap page in)
    • 페이지 폴트 발생 시 memory access도 발생하지만 swap에 비해 굉장히 작은 값이므로 무시한다.
  • Example
    • memory access time = 200 ns
    • Average page-fault service time = 8 ms
    • EAT = (1-p) * 200 + p * 8,000,000 = 200 + p * 7,999,800
    • 만약 1000번 중 한 번의 접근에 페이지 폴트 발생 시 (p = 1/1000)
      • EAT = 8.2 ms, 40배 느려진다. (200ns와 비교 시)
    • 10% 이하로 성능 저하를 낮추고 싶다면
      • 200 + 7,999,800 * p < 200 * 1.1
      • p < 0.0000025
        • 399,990번 중에 1번 페이지 폴트가 발생해야 한다.

(3) 스왑 공간의 관리

  • 스왑 공간에서의 디스크 I/O는 일반적으로 파일 시스템에서의 입출력보다 빠르다.
  • 두 가지 방법
    • 프로세스 시작 시 전체 파일 이미지를 스왑 공간에 복사한 다음 스왑 공간에서 요구 페이징을 수행
    • 프로 그램을 처음 시작시킬 때에는 파일 시스템으로부터 요구 페이징을 처리하지만 , 그 페이지들이 교체될 때는 스왑 공간에 페이지를 기록한다.

 

4. 쓰기 시 복사 (Copy-on-write)

  • fork() 시스템 콜을 통해 프로세스를 생성할 때는 페이지 공유와 비슷한 기법으로 첫 요구 페이징조차 생략하는 것이 가능하다.
  • fork() 호출 시 부모의 페이지들을 다 복사해오는 대신 쓰기 시 복사(copy-on-write) 방식을 사용한다.
  • 이 방식에서는 자식 프로세스가 시작할 때 부모의 페이지를 당분간 함께 사용한다.

  • 둘 중 한 프로세스가 공유 중인 페이지에 쓸 때 그 페이지의 복사본이 만들어진다
  • 수정하는 페이지들에 대해서만 복사본이 생긴다.
  • 수정되지 않는 페이지들은 자식과 부모 간에 계속 공유될 수 있다.
  • Windows, Linux, macOS 등을 포함한 여러 운영체제에서 사용되고 있다.
반응형

댓글