Virtual Memory

🗓️

가상 메모리

  • 가상 메모리라는 것은 프로세스 전체가 메모리 내에 올라오지 않더라도 실행이 가능하도록 하는 기법이다.
  • 이 기법의 주요 장점중 하나는 사용자 프로그램이 물리 메모리 보다 커져도 된다는 점이다.

배경

  • 많은 경우에 프로그램 전체가 한꺼번에 메모리에 늘 올라와있어야 하는것은 아니다 아래의 예시가 있다.
    • 프로그램에는 잘 발생하지 않는 오류 상황을 처리하는 코드가 종종 존재한다. 이러한 오류들은 거의 발생하지 않으므로 실행되지 않는다.
    • 배열, 리스트, 테이블 등은 필요 이상으로 많은 공간을 점유할 수 있다. 실제로 10 by 10만 사용하는데도 불구하고 100 by 100으로 선언될 수 있다.
    • 프로그램 내의 어떤 옵션이나 기능은 거의 사용되지 않는다.
  • 만일 프로그램을 일부분만 메모리에 올려놓고 실행할 수 있다면 다음과 같이 많은 이점이 있다.
    • 프로그램은 물리 메모리 크기에 더이상 제약 받지 않게 된다. 매우 큰 가상 주소 공간을 가정하고 프로그램을 만들 수 있어 프로그래밍이 간단해진다.
    • 각 사용자 프로그램이 더 작은 메모리를 차지하므로 더 많은 프로그램을 동시에 실행 할 수 있다. 이에 따라 응답시간은 늘어나지 않으면서 사용률과 처리율이 옾아진다.
    • 프로그램을 메모리에 올리고 스왑하는데 필요한 입출력 횟수가 줄어들기 때문에 프로그램들이 보다 빨리 실행된다.
  • 가상 메모리는 실제 물리 메모리 개념과 사용자 논리 메모리 개념을 분리한 것이다.
  • 프로세스의 가상 주소 공간은 그 프로세스가 메모리에 저장되는 논리적인 모습을 말한다.
  • 위 그림과 같이 특정 논리 주소에서 0번지로 시착해 연속적인 공간을 차지한다.
  • 물리 메모리는 페이지 프레임들로 구성된다.
  • 프로세스에 할당된 페이지 프레임들이 실제적으로는 연속적인것들이 아님을 위 그림은 나타낸다.
  • 물리적인 페이지 프레임을 논리적인 페이지로 매핑하는 것MMU에 달렸다.
  • 위 그림을 보자
    • 힙은 동적 할당 메모리를 사용해 주소에서 위로 확장된다
    • 스택은 함수 호출을 거듭함에 따라 아래로 확장된다.
    • 공백을 포함하는 가상 주소를 스페어 주소 공간이라 한다.
  • 가상 메모리는 페이지 공유를 통해 파일이나 메모리가 둘 또는 그 이상의 프로세스들에 의해 공유되는 것을 가능하게 된다.
    • 시스템 라이브러리가 여러 프로세스들에게 공유될 수 있다. 일반적으로 라이브러리는 읽기만 허용되는 상태로 프로세스 주소 공간에 매핑된다.
    • 프로세스들이 메모리를 공유할 수 있다. 공유 메모리를 통해 프로세들은 통신한다.
  • 페이지는 fork() 시스템 호출을 통한 생성 과정 중 공유 될 수 있어 프로세스 생성 속도를 높힐 수 있다.

요구 페이징 (Demand Paging)

  • 요구 페이징 : 실행 과정 초기에 필요한 것들만 메모리에 로딩하는 전략. 가상 메모리 시스템에서 사용한다.
  • 가상 메모리는 대게 요구 페이징으로 구현된다.
  • 게으른 스왑 : 요구 페이징 기법이 스왑과 비슷하지만 해당 페이지가 필요하지 않는 한 디스크로부터 메모리에 적재하지 않는다는 개념. 페이저 pager라고도 한다. 스왑은 전체 프로세스를 페이징하는 반면 페이저는 프로세스 내의 개별 페이지들을 관리한다.

기본 개념

  • swap in 시에 페이저는 프로세스가 다시 swap out 되기 전에 실제로 사용될 페이지들이 어떤 것인지 추측한다.
  • 페이저는 프로세스 전체를 swap in 하는 대신 실제 필요한 페이지들만 메모리로 읽어온다.
  • 페이지 테이블의 valid-invalid 기법을 사용하여 어느 페이지가 메모리에 올라와있는지 구별한다.
  • 프로세스가 메모리에 존재하는 페이지들만 접근하는 한 실행은 정상적으로 실행된다.
  • 메모리에 올라와있지 않은 페이지를 접근하려고 하면 페이지 테이블 항목이 invalid이므로 페이지 폴트 트랩 page fault trap을 발생시킨다.
    • 페이징 하드웨어는 페이지 테이블을 이용한 주소변환 과정에서 invalid 비트를 발견하고 운영체제에 트랩을 건다.
  • 페이지 폴트 트랩을 처리하는 과정은 다음과 같다
    1. 프로세스에 대한 내부 테이블을 검사해서 그 메모리 참조가 vaild인지 invalid인지 알아낸다.
    2. 만약 무효한 페이지에 대한 참조라면 프로세스는 중단된다. 만약 유효한 참조인데 페이지가 아직 메모리아 올라오지 않았다면 그것을 디스크로부터 가져와야한다.
    3. 빈 공간, 자유 프레임을 찾는다.
    4. 디스크에 새로이 할당된 프레임으로 해당 페이지를 읽어들이도록 요청한다.
    5. 디스크 읽기가 끝나면, 이 페이지가 이제는 메모리에 있다는 것을 알리기 위해 페이지 테이블을 갱신한다. 프로세스가 유지하고 있는 내부 테이블을 수정한다.
    6. 트랩에 의해 중단되었던 명령어를 다시 수행한다. 이제 프로세스는 마치 그 페이지가 항상 메모리에 있었던것 처럼 해당 페이지를 접근할 수 있다.
  • 순수 요구 페이징 : 어떤 페이지가 필요해지기 전에는 결코 그 페이지를 메모리로 적재하지 않는 방법. 메모리에 페이지가 하나도 안올라와있는 상태에서도 프로세스를 실행시킬 수 있다는 조건. 인스트럭션 포인터를 프로세스의 첫 명령어로 설정하는 순간 이 명령이 메모리에 존재하지 않는 페이지에 있으므로 페이지 폴트를 발생시킨다.
  • 요구 페이징을 지원하기 위한 플요한 하드웨어는 페이징과 스왑을 위한 하드웨어와 동일하다.
    • 페이지 테이블 : 보호 비트들의 특별한 값, valid-invalid 비트를 통한 항목 설정
    • 보조 기억 장치 : 메인 메모리에 없는 모든 페이지들을 갖고 있다. 이 목적을 위해 사용하는 디스크 영역을 swap 공간이라고 한다.
  • 페이지 폴트가 발생된 후 명령어를 다시 시작할 수 있어야 한다.
    • 중단된 프로세스 상태를 보관해두면 다시 이 프로세스를 시작할 때 해당 페이지가 메모리로 올라와서 접근 가능하다는것 외에는 정확히 같은 위치, 같은 상태에서 프로세스를 다시 수행할 수 있다.
  • 만약 페이지 폴트가 인스트럭션 fetch시에 발생했다면 명령어를 메모리로 읽어온 후 다시 수행을 시도하면 된다.
  • 만약 피연산자를 fetch하는 동안에 페이지 폴트가 발생했다면 나중에 그 명령어를 다시 읽어오고 해독하여 피연산자를 fetch하면 된다. 페이징은 컴퓨터 시스템에서 CPU와 메모리 사이에 들어간다. 일반 프로그래머의 눈에는 전혀 드러나지 않아야 한다. 글개서 어느 시스템에서나 페이징을 쉽게 추가할 수 있는는 것으로 생각할 수 있다. 이는 페이지 폴트가 심각한 오류인 요구 페이징이 없는 환경에서는 사실이지만, 페이지 폴트가 단순히 한 페이지를 메모리에 로딩하고 다시 실행을 계속해야 하는 상황에서는 쉽지 않은 일이다.

요구 페이지의 성능

  • 유효 접근 시간 : 페이지 폴트가 발생하지 않는 이상 유효 접근 시간은 메모리 접근 시간과 같다. 그러나 페이지 폴트가 발생하면 디스크로부터 관련된 페이지를 읽어와야 하는데 많은 비용이 발생한다. (과정 생략)
  • 페이지 폴트를 처리하는 시간은 다음 3개의 큰 구성요소로 이루어진다.
    1. 인터럽트의 처리
    2. 페이지 읽기
    3. 프로세스 재시작
  • 유효 접근 시간은 페이지 폴트 비율에 비례한다.
  • 요구페이징은 또한 스왑공간을 관리한다.

Copy-on-write

  • 첫 명령어가 포함된 페이지를 요구 페이징 함으로써 프로세스를 빠르게 시작시킬 수 있다.
  • 그러나 fork() 호출을 통해 프로세스를 생성할때는 페이지 공유와 비슷한 기법으로 첫 요구 페이징조차 생략하는것이 가능하다.
  • fork()는 부모 프로세스와 똑같은 자식 프로세스를 만들어주는 것이다.
  • 부모의 페이지를 모두 복사해와도 곧바로 exec()되므로 복사한 페이지들이 쓸모없어진다.
  • 그래서 모든 페이지를 복사해오는 대신 copy-on-write 방식을 사용한다.
  • 이 방식에서는 자식 프로세스가 시작할 때 부모의 페이지를 당분간 함께 사용하도록 한다. 이때 공유되는 페이지를 copy-on-write 페이지라고 한다.
    • 둘 중 한 프로세스가 공유중인 페이지에 쓸 때 그 페이지의 복사본이 만들어진다.
  • fork() 이후 수정될 수 있는 페이지만 복사된다.
  • 수정 될 수 없는 페이지는 그대로 copy-on-write 복사본이 공유된다.
  • copy-on-write 처리 과정에서 페이지 복사본을 만들 때 빈 페이지는 zero-fill-on-demand 하여 0으로 이전 내용을 모두 지운다.
  • vfork(); 생략

페이지 교체

  • 멀티 프로그래밍의 정도(degree)를 올리면 메모리 과할당이 발생한다.
  • 과할당의 과정은 다음과 같다
    • 사용자 프로세스가 실행 중에 페이지 폴트가 발생한다. 운영체제가 필요한 페이지가 디스크의 어디에 위치하고 있는지 알아내면 빈 프렝미이 없음을 발견한다.
    • 이 시점에서 운영체제는 프로세스 하나를 swap out하여 그 프로세스의 프레임들을 해제하고 멀티 프로그래밍의 정도를 낮출 수 있다.

기본적인 페이지 교체

  • 페이지 교체의 과정
    1. 디스크에서 필요한 페이지의 위치를 알아낸다
    2. 빈 페이지 프레임을 찾는다
      1. 빈 프레임이 있다면 사용한다.
      2. 없다면 제거될 프레임을 선정하기 위해 페이지 교체 알고리즘을 가동시킨다
      3. 제거될 페이지를 디스크에 기록하고, 관련 테이블을 수정한다.
    3. 빼앗은 프레임에 새 페이지를 읽어오고 테이블을 수정한다
    4. 페이지 폴트가 발생한 시점부터 사용자 프로세스를 계속한다
  • 요구 페이징 시스템은 프레임 할당 알고리즘페이지 교체 알고리즘을 해결해야한다

FIFO 페이지 교체

  • 가장 간단한 페이지 교체 알고리즘
  • 페이지를 교체해야할 때 메모리에 올라온지 가장 오래된 페이지를 방출한다.
  • Queue
  • Belady의 모순 : 프로세스에 프레임을 더 줬는데 오히려 페이지 폴트율은 증가하는 현상.

최적 페이지 교체 (Optimal page replacement)

  • 앞으로 가장 오랜시간동안 사용되지 않을 페이지를 찾아서 교체하는 기법
  • 예측은 불가능하기 때문에 구현이 불가능하다.

LRU 페이지 교체 (Least-recently-used page replacement)

  • 가장 오랫동안 사용되지 않은 페이지를 교체한다.
  • Belady의 모순 현상이 없다.
  • LRU알고리즘은 각 페이지마다 마지막 사용 시간을 기록한다.
  • 프레음들을 최근 사용된 시간 순서로 파악할수 있는 두가지 방법이 있다.
  • Counters : 각 페이지 항목마다 사용 시간 필드를 넣고 CPU에 논리적인 시계나 카운터를 추가한다. 매 메모리 접근시마다 시간을 증가시킨다.
  • Stack 스택 : 페이지번호의 스택을 유지하는 방법이다. 페이지가 참조될 때 마다 페이지 번호는 스택의 안쪽에서 top으로 올라간다.
  • 단점 : TLB레지스터 이상의 하드웨어 지원이 있어야 한다. 메모리 참조때마다 값이 갱신된다. 그래서 소프트웨어로 인터럽트를 사용하면 매우 느리다.

LRU 근사 페이지 교체

Additional Reference bits Algorithm

  • 페이지 참조가 일어날때마다 참조 비트를 설정한다.
  • 참조비트
    • 처음에 0으로 초기화된다.
    • 페이지가 참조 될 때 마다 1로 된다.
    • 교체되면 0으로 된다
  • 페이지의 사용 순서는 모르지만 페이지의 사용 여부는 알 수 있다.

Second-Chance Algorithm

  • FIFO 교체전략 사용
  • 참조비트가 0이면 교체를 한다
  • 참조비트가 1이면 Second-change를 한번 더 사용하고 다음 FIFO 페이지를 선택한다.

Enhanced Second-Change Algorithm

  • (생략)

카운팅 기반 페이지 교체 (Counting-Based page replacement)

  • 페이지를 참조할 때 마다 카운팅해 다음과 같은 두가지 기법을 만들 수 있다.
  • LFU알고리즘 : 참조 횟수가 가장 적은 페이지를 교체하는 방법이다.
  • MFU알고리즘 : 참조 횟수가 가장 적은 페이지가 가장 최근 참조된 것이고 앞으로 사용될 것이다.
  • 최적 페이지 교체 정책에 제대로 근사하지 못하기 때문에 둘다 사용되지 않는다.

페이지-버퍼링 알고리즘

  • (생략)

어플리케이션과 페이지 교체

    몇몇 경우에는 운영체제의 가상 메모미를 통해 데이터를 접근하는 어플리케이션이 운영체제가 전혀 버퍼링 기능을 제공하지 않는 경우에 비해 오히려 안 좋은 성능을 보일 때가 있다. 대표적인 예는 나름대로의 메모리 관리와 입출력 버퍼링을 수행하고 있는 데이터베이스다. 이러한 어플리케이션들은 범용적인 알고리즘을 구현해야하는 운영체제에 비해 스스로의 메모리와 디스크 사용 방식을 더 잘 이해하고 있다. 그러나 운영체제가 입출력 버퍼링을 하고 또 어플리케이션이 마찬가지로 버퍼링 하게 되면 같은 입출력에 대해 메모리가 양쪽으로 두배 사용된다.
    다른 예로, 데이터 웨어하우스는 자주 연속적인 대량의 읽기 작업 후에 계산과 쓰기 작업을 수행하게 된다. LRU 알고리즘은 오래된 페이지들을 버리고 새로운 페이지들을 유지하려고 하는데, 어플리케이션은 새로운 페이지에 비해 오래된 페이지를 읽을 가능성이 더 높다. 이때는 MFU가 LRU보다 더 효율적일 수 있다.
    이러한 문제들 때문에 몇몇 운영체제는 특별한 프로그램들에는 디스크 파티션을 파일 시스템 구조가 아닌 단순한 논리적인 블록들의 순차적인 배열로서 사용할 수 있게 해 주는 기능을 갖추고 있따. 이 배열은 종종 raw disk라고 불리며 여기에 대한 입출력은 raw 입출력이라는 용어를 사용한다. raw 입출력은 파일 시스템의 요구 페이징, 파일 잠금, 선반입, 공간할당, 디렉터리, 파일이름 드으이 모든 파일 시스템 서비스를 거치지 않는다. 특정 어플리케이션들이 raw파티션을 이용해 자신만의 특수한 저장 장치 서비스를 구현하는 것이 효율적인데 비해 대부분의 어플리케이션들은 정상적인 파일시스템 서비스를 이용해 동작하는 것이 더 좋은 성능을 보인다는것을 주의해야 한다.

프레임 할당

  • 예를 들어 1KB 크기의 페이지로 구성된 128KB메모리를 갖는 단일 사용자 시스템이라면 128개의 프레임을 갖는다. 운영체제가 모든 버퍼나 테이블 공간을 가용 프레임 리스트에서 할당받도록 할 수 있다. 이런 공간ㄷ르이 운영체제에 의해 사용되지 않을 때는 사용자 페이징을 위해 사용될 수 있다. 언제나 가용 프레임 리스트에 3개의 프렝미은 예비로 남겨두고자 한다. 그러면 실제 페이지 폴트 발생 시에는 가용 프레임이 존재하게 된다. 페이지스오바을 처리하는 동안 사용자 프로세스는 계속해서 수행하면서도 교체 대상이 선택되고 디스크로 저장될 수 있다. 다른 변경들도 가능하지만 기본적인 전략은 명확하다. 즉, 사용자 프로세스는 어떤 가용 프레임이든 할당받아야 한다.

최소로 할당해야하는 프레임의 수

  • 메모리 할당에는 제약이 존재한다.
    • 페이지 공유가 없으면 가용 프레임 수 보다 더 많이 할당할 수 없다.
    • 최소한 몇 페이지는 할당해야만 한다.
  • 프로세스에 할당되는 프레임 수가 줄어들면 페이지 폴트율은 증가하고 프로세스 실행은 늦어지게 된다. 또한 명령어 수행이 완료되기 전에 페이지 폴트가 발생하면 그 명령어를 재실행해야하는 점을 기억하자.
    • 따라서 하나의 명령어가 참조하는 모든 페이지는 동시에 메모리에 올라와있어야 그 명령어의 수행이 끝날 수 있게 된다.
  • 프로세스당 최소 프레임 수는 구조에 의해 결정되고 최대 할당 수는 가용 물리 메모리에 의해 결정된다.
  • 이 사이에는 상당히 많은 프레임 할당 가능성이 존재한다.

할당 알고리즘

  • 균등 할당 : 모든 프로세스에게 똑같이 프레임을 할당하는 방법
  • 비례 할당 방식 : 요구하는 프레임을 바탕으로 할당하는 방법

전역 할당 대 지역 할당

  • 우선순위를 가지는 프레임 경쟁에서 실행할 수 있는 교체 기법.
  • 전역 교체 : 프로세스가 교체할 프레임을 다른 프로세스에 속한 프레임을 포함한 모든 프레임으로 대상을 찾는 경우. 교체가 일어나면 할당된 프레임의 수가 변할 수 있다.
  • 지역 교체 : 각자 프로세스가 자기에게 할당된 프레임들 중 교체될 대상을 선택할 수 있는 경우. 프로세스에 할당된 프레임의 수는 변하지 않는다.
  • 일반적으로 전역 교체가 더 좋은 성능을 타나낸다.

NUMA; 비균등 메모리 접근

  • 지금까자의 논의는 모든 메인 메모리는 동등하게 또는 적어도 동일하게 접근된다는 것을 가정했다.
    • 그러나 실제로 그렇지 않다.
  • 종종 복수의 CPU를 가진 시스템에서 특정 CPU는 메인 메모리의 일정 영역을 다른 영역보다 빠르게 접근할 수 있다.
  • 메모리 접근 시간이 현저하게 차이나는 시스템을 모두 비균등 메모리 접근 NUMA 시스템이라고 한다.
  • 어느 페이지를 어느 프레임에 할당하냐는 정책이 NUMA성능에 큰 영향을 미친다.
  • 이 정책의 목표는 프로세스가 실행중인 CPU에 가능한 가장 가까운 메모리 프레임이 할당되도록 하는 것이다. (최소 지연 시간)

Thrashing

  • 프로세스에게 할당된 프레임 수가 인스트럭션 집합 구조가 요구하는 최소한의 수보다 적게 되면, 그 프로세스는 실행을 한동안 일시중단 한다.
  • 충분한 프레임을 할당받지 못한 프로세스는 페이지 폴트가 바로 발생할 것이다. 이때 페이지 교체가 필요하지만 이미 활발하게 사용되는 페이지들만 이루어져있으므로 어떤 페이지가 교체되든 바로 다시 필요해 질 것이다. 결과적으로 바로 반복해서 페이지폴트가 발생하며 교체된 페이지는 얼마 지나지 않아 읽어올 필요가 생긴다.
  • 스레싱 : 과도한 페이지 작업을 일컫는 말. 어떤 프로세스가 실제 실행보다 더 많은 시간을 페이징에 할애하는 경우 스레싱이 발생했다고 한다.

스래싱의 원인

  • 위 그림은 멀티 프로그래밍의 정도(degree)에 따른 CPU이용률의 그래프를 보여준다. 처음에는 멀티 프로그램의 정도가 높아짐에 따라 CPU의 이용률도 높아진다. 증가속도가 감소하기는 하지만 최댓값에 도달하기 까지 증가한다. 그러나 멀티프로그래밍의 정도가 그 이상으로 더 커지면 스레싱이 일어나게되고 CPU의 이용률은 급격히 떨어진다. 따라서 이 지점에서는 CPU의 이용률을 높이고 스레싱을 중지시키기 위해 멀티 프로그래밍의 정도를 낮춰야만 한다.
  • 스레싱은 지역 교체 알고리즘이나 우선순위 교체 알고리즘을 사용하면 제한할 수 있다.
  • 그러나 스레싱이 일단 시작되면 여러 프로세스가 대부분의 시간을 디스크 큐에서 보내게 되므로 스레싱과 관련이 없던 프로세스도 디스크 입출력 시간이 엄청나게 걸린다.
  • 스레싱 현상을 방지하기 위해서는 각 프로세스가 필요로 하는 최소한의 프레임 수를 보장해야 한다.
    • 먼저 프로세스가 실제로 사용하고 있는 프레임의 수가 몇 개 인가를 알아보는 지역성 모델을 기반으로 한다.
    • 지역성 모델 : 프로세스가 실행될 때에는 항상 어떤 특정한 지역에서 메모리를 집중적으로 참조하는 것을 말한다. 지역이란, 집중적으로 함께 참조되는 페이지들의 집합을 의미한다. 한 프로그램읜 여러개의 지역으로 구성되있고, 이 지역은 서로 겹칠 수 있다.
  • 지역은 프로그램 구조나 자료구조에 의해 정의된다. 어떤 프로세스에게 현재 지역성을 포함하기에 충분한 프레임을 제공해 준다고 가정하자, 글 프로세스는 현재 지역의 모든 페이지가 메모리로 올라올 때 까지는 페이지 폴트를 발생시키지만 그 후에는 지역이 변경되기 전까지는 페이지 폴트를 발생시키지 않게 된다. 필요로 하는 지역성의 크기보다 적은 프레임을 할당하게 되면, 그 프로세스는 접근해야 하는 모든 페이지를 메모리에 유지할 수 없기 때문에 지속적으로 페이지 폴트를 발생시키게 된다. 즉, 스레싱이 일어난다.

작업 집합 Working-set 모델

  • 메모리 접근은 특정 페이지를 지역적으로 접근한다.
  • 지역성을 기반으로 한다. 개념적으로 윈도우(t의 슬라이딩)을 가지고 있다.
  • working-set window를 delta로 지정한다.
    • 페이지가 사용되고 있으면 delta내에 있고
    • 페이지가 사용되지 않으면 delta밖에 있을 것이다.
  • delta밖에 있는것을 희생자로 선정하여 페이지 교체를 하면 된다.

페이지 폴트 빈도

  • 스레싱이란 페이지 폴트율이 높은 것을 의미한다. 우리가 우너하는 것은 페이지 폴트율을 조절하는 것인데, 페이지 폴트율이 너무 높으면 그 프로세스가 더 많은 프레임을 필요로 한다는 의미고, 페이지 폴트율이 너무 낮으면 프로세스가 너무 많은 프레임을 갖고 있다는 것을 의미한다. 따라서 페이지 폴트율의 상한과 하한을 정해놓고, 만약 페이지 폴트율이 상한을 넘으면 그 프로세스에게 프레임을 더 할당하고, 하한보다 낮으면 그 프로세스의 프레임 수를 줄인다.
  • 이렇게 함으로써 직접적으로 폴트율을 관찰하고 조절함으로써 스레싱을 방지할 수 있다. (생략한) 작업 집합 전략에서와 같이 프로세스를 swap out해야만 할 필요도 있다. 만약 페이지 폴트율이 높아졌는데, 그 프로세스에게 줄 수 있는, 즉 놀고 있는 프레임이 없으면 한 프로세스를 선택하여 그 프로세스를 예비 저장장치로 swap out 시켜야 한다. 이렇게 되면 그 프로세스에게 할당되었던 프레임은 높은 페이지 폴트율을 갖는 다른 프로세스에게 분배된다.

메모리 매핑 파일

  • 메모리 매핑 : 프로세스의 가상 공간 중 일부를 관련된 파일에 할애하는 것. 디스크 입출력을 메모리 참조 방식으로 대신한다.

기본 기법

  • 파일의 메모리 매핑은 프로세스의 페이지 중 일부분을 디스크에 있는 파일의 블록에 매핑함으로써 이루어진다.
  1. 첫번째 접근은 일반적인 요구 페이징 과정에 따라 페이지 폴트를 발생
  2. 그 파일 내용 중 페이지 크기만큼 해당 부분이 파일 시스템으로부터 메모리 페이지로 읽혀들어온다.
  3. 파일 read/write는 일반적인 메모리 엑세스와 같이 처리된다. read(), write()를 사용하는 오버헤드 없이 파일을 메모리를 통하여 조작하면 단순하고 더 빠르게 파일을 접근하고 사용할 수 있다.
  • 여러 프로세스들이 데이터 공유를 위해 파일을 공유할 수 도 있다. 파일을 공유하는 프로세스들의 페이지 매핑 케이블은 모두 그 파일에 대응하는 물리메모리 상의 페이지를 가리킨다. 이 페이지에는 디스크 파일의 내용이 올라와있다. 사실 공유메모리를 메모리 매핑 파일을 이용해 구현하는 것은 매우 자주 있는 일이다. 이러한 방식에서는 동일한 파일을 프로세스들의 가상 주소 공간에 메모리를 매핑하게 함으로써 프로세스들은 공유 메모리를 사용하여 통신할 수 있다. 메모리 매핑된 파일은 통신하는 프로세스들 사이의 공유 메모리 영역으로서 동작한다. 우리는 이미 POSIX 공유메모리 객체를 생성하고 각 통신 프로세스가 이 객체를 자신의 주소 공간에 메모리 매핑 하는 것을 보았다.

메모리 매핑 입출력

  • 입출력 작업 시에 각 입출력 처리기는 명령어와 전송할 데이터를 담기 위한 레지스터를 포함하고 있다.
  • 이러한 레지스터와 시스템 메모리 간의 데이터 전송을 위해서는 대개 특별한 입출력 명령어가 사용된다.
  • 대다수의 컴퓨터 구조는 메모리 매핑 입출력 기능을 제공하고 있다.
  • 특정 메모리 영역을 장치 레지스터들을 매핑할 수 있도록 유보해 둔다. 이러한 주소에 대한 읽기쓰기 작업은 장치 레지스터의 데이터 전송으로 처리된다.
  • 화면에 문자를 표시하는 것은 적절한 위치의 메모리에 쓰는것으로 손쉽게 처리된다.

커널 메모리의 할당

  • 사용자 모드에서 수행중인 프로세스가 추가적인 메모리를 요구하면 커널이 관리하는 가용페이지 프레임에서 페이지들이 할당된다. 가용 리스트는 페이지 교체 정책들에 의해 물리 공간상에 여기저기 흩어져있는 페이지들로 채워진다.
  • 커널 메모리는 보통 사용자 모드 프로세스에게 할당해주기 위한 페이지 리스트와는 별도로 메모리 풀에서 할당 받는다. 이렇게 하는 이유는 다음과 같다
  1. 커널은 다양한 크기의 자료구조를 위해 메모리를 할당 받는다. 이 자료구조들은 페이지 크기보다 작은 크기를 갖기도 한다. 때문에 커널은 메모리를 조심스럽게 사용해야 하고 단편화에 의한 낭비를 최소화 하고자 한다. 많은 운영체제들이 커널 코드나 데이터를 페이징 하지 않기 때문에 특히 더 중요하다.
  2. 사용자 모드 프로세스에 할당되는 페이지들은 물리 메로리상에서 굳이 연속된 것일 필요는 없다. 그러나 가상 메모리 인터페이스를 통하지 않고 물리 메모리에 직접 접근하는 특정 하드웨어 장치는 물리적으로 연속적인 메모리를 필요로 하는 경우가 있다.

기타 고려 사항

  • 페이징 시스템이 효과적으로 실행되기 위해서는 페이지 교체 알고리즘과 할당 정책 외에도 고려할것이 있다.

프리 페이징 Prepaging

  • 순수요구 페이징 시스템은 프로세스가 시작될 때 많은 페이지 폴트가 발생한다. 최초의 지역을 메모리로 로딩할때 생기는 현상이다. 이 현상은 swap out된 프로세스를 다시 불러올때도 발생한다.
  • 프리페이징은 과도한 페이지 폴트를 방지하기 위해 관련된 모든 페이지를 한꺼번에 메모리 내로 가져오는 기법이다.