6. 가상메모리 관리
가상메모리
메모리 관리자는 프로세스가 필요로 하는 데이터를 언제 메모리로 가져올지 결정하는 것을 가져오기 정책이라고 한다.
가져오기 정책은 프로세스가 요청할 때 메모리로 가져오는 방법이 일반적이다. 이를 요구 페이징 이라고 한다.
요구페이징
용량이 큰 프로세스를 실행할 때 운영체제는 프로세스를 구성하는 모듈을 전부 메모리에 올리지 않는다.
그 이유는 메모리를 효율적으로 관리하기 위해서, 모듈을 모두 가져오면 응답 속도가 느려지기 때문에 응답 속도를 높이기 위해서이다.

특정 기능을 요구할때 해당 모듈만 메모리에 올리는 것에서 우리는 메모리 절약, 메모리의 효율적 관리, 응답 속도 향상 등의 기대 효과를 얻을 수 있다.
이처럼 사용자가 요구하는 해당 페이지를 메모리에 가져오는 것을 요구 페이징이라고 한다.
Vs 미리 가져오기
미리 가져오기는 요구 페이징과는 반대로 앞으로 필요할 것이라고 생각되는 페이지를 미리 가져오는 방식이다.
미리 가져오기의 대표적인 예가 캐시이다. 하지만 이렇게 미리 가져올 경우 그 데이터가 생각과는 다르게 쓸모 없는 페이지까지 메모리 공간을 잡아먹으며 오버헤드가 발생한다.
그래서 현대 운영체제들은 기본적으로 요구페이징을 채택해서 사용한다.
가상 메모리의 크기는 물리 메모리와 스왑 영역을 합친 크기이다.
키워드 기억해보자 스왑인과 스왑아웃?
가상 메모리 시스템에서 사용자의 프로세스는 물리 메모리와 스왑 영역 중 한 곳에 있다.
스왑 영역에 있는 경우
하나는 요구 페이징으로 인해 처음부터 물리 메모리에 올라 가지 못한 경우
다른 하나는 메모리가 꽉 차서 스왑 영역으로 옮겨진 경우이다.
모든 경우에서 페이지 테이블에는 페이지가 메모리에 있는지, 스왑 영역에 있는지를 표시해야하는데
이때 사용하는 비트가 유효 비트 이다.
흐름
- CPU 가 특정 페이지에 접근하는 명령어를 실행한다.
- 해당 페이지가 현재 메모리에 있을 경우 (유효 비트가 1인 경우) CPU는 페이지가 적재된 프레임에 접근한다.
- 해당 페이지가 현재 메모리에 없을 경우 (유효 비트가 0인 경우) 페이지 폴트가 발생한다.
- 페이지 폴트 처리 루틴은 해당 페이지를 메모리로 적재하고 유효 비트를 1로 설정한다.
- 다시 1번을 수행한다.
요구 페이징이 안정적으로 작동하려면 해결해야 하는 문제
- 페이지 교체
- 프레임 할당
페이지 교체 알고리즘
- 요구 페이징 기법으로 페이지를 적재하다가 보면 언젠가는 메모리가 가득 차게 된다.
- 당장 실행에 필요한 페이지를 적재하려면 적재된 페이지를 보조 기억 장치로 내보내야한다.
- 어떤 페이지를 내보낼지 결정하는 알고리즘이 페이지 교체 알고리즘이다.
페이지 폴트란 프로그램이 접근하려는 데이터나 코드가 현재 메모리에 로드되어 있지 않을 때 발생하는 현상이다.
좋은 페이지 교체 알고리즘의 기준
- 페이지 폴트가 적은 알고리즘
- why? 페이지 폴트가 발생하면 보조기억장치에 접근해야해서 성능 저하가 발생하기 때문이다.
페이지 폴트의 횟수는 어떻게 알 수 있을까
- 페이지 참조열을 통해서 우리는 알 수 있다.

어떤 CPU 가 위와 같은 순서로 페이지를 참조했다고 가정한다.

이중에서 연속된 페이지 참조를 생략한 위와 같은 문자열을 페이지 참조열이라고 한다.
연속된 페이지를 생략하는 이유는 연속된 페이지에 두번 접근하면 이미 페이지 폴트 처리 루틴이 끝난 후에 처리가 되기 때문에 연속된 페이지가 있다고 페이지 폴트가 발생하지 않는다.
FIFO 페이지 교체 알고리즘
- 가장 단순한 방식
- 메모리에 가장 먼저 올라온 페이지부터 내쫓는 방식

페이지 참조열는 위와 같고 프레임은 3개가 있다고 가정해보자
이 알고리즘은 구현 자체가 간단하지만 마냥 좋지는 않다.
프로그램 내내 사용될 페이지가 있다면 먼저 적재했다고 내쫓으면 안된다.
하지만 FIFO 알고리즘에서는 내내 사용할 페이지도 내쫓을 수 있기 때문에 성능면에서 좋지 않다.
FIFO에서 나온 보완책
2차 기회 페이지 교체 알고리즘
기본적으로는 메모리에서 가장 오래 머무른 페이지를 내쫓는다.
하지만 페이지 참조 비트가 1로 CPU가 참조한 적이 있는 페이지일 경우 바로 내쫓지 않고 적재된 시간으로 현재 시간으로 설정하고 다시 맨 끝으로 보낸다. 즉 가장 최근에 적재된 페이지로 간주한다는 뜻
그리고 가장 오래 머무른 페이지로 참조 비트가 0이고 CPU가 참조한 적이 없는 페이지 일 경우 이 페이지를 내보낸다.

원래 FIFO 였다면 페이지3 을 쫓아 내야한다. 하지만 현재 상황에서 페이지 3의 참조 비트는 1

참조 비트를 0으로 바꾸고 페이지 3을 끝으로 보낸다.
그 후 페이지 1의 참조 비트를 참조하고 0 이기 때문에 페이지 1을 내쫓는다.
최적 페이지 교체 알고리즘
- CPU에 의해 참조되는 횟수를 고려한다.
- 메모리에 오래 남아야 할 페이지는 자주 사용될 페이지이다.
- 메모리에 없어도 될 페이지는 오랫동안 사용되지 않을 페이지이다.

앞으로 사용 빈도가 가장 낮은 페이지를 교체한다는 뜻이다.
5번을 적재하는 타이밍에서 위 참조열을 보면 앞으로 가장 오랫동안 사용하지 않을 페이지는 1번으로 보인다.
그렇기 때문에 1번을 내쫓고 5번을 적재한다.
4번을 적재하는 타이밍에서 위 참조열을 보면 2 3이 남아 있다. 그렇기 때문에 적재된 2 3 5 중에서 5를 내쫓고 4를 적재한다.
이름 그대로 가장 낮은 페이지 폴트율을 보장할 수 있는 알고리즘이라고 한다.
하지만 실제 구현이 어렵다고 한다;;
앞으로 오랫동안 사용되지 않을 페이지를 어떻게 예측할 것인가
그래서 다른 페이지 교체 알고리즘의 성능을 평가하기 위한 척도로 이론적인 방식으로 사용된다고 한다.
최적 알고리즘에 비해 페이지 폴트가 얼마나 발생하는가로 평가
LRU 페이지 교체 알고리즘
가장 오래 사용되지 않은 페이지를 교체한다.
최근에 사용되지 않은 페이지는 앞으로도 사용되지 않지 않을까 에서 나온 알고리즘

5번을 적재할 타이밍이 왔다. LRU 알고리즘을 기반으로 무슨 페이지를 내보내겠는가?
그렇다 참조열을 보면 가장 오랜 사용되지 않은 페이지는 2번이다.
2번을 적재할 타이밍 5 3 1 중에서 가장 오래 동안 사용되지 않은 1번이 나가게 된다.
4번이 적재될 타이밍 5 3 2 중에서 5번이 가장 오래 동안 사용되지 않았기 때문에 5번이 나간다.
LRU 에서 파생된 알고리즘이 여러가지 있다고 한다.
프레임 할당과 스레싱
페이지 폴트가 자주 일어나는 이유는 나쁜 교체 알고리즘 때문만은 아니다.
하나의 프로세스가 사용할 수 있는 프레임 자체가 적어도 페이지 폴트는 자주 일어난다.
극단적인 예로 프레임이 무한히 많다고 하면 당연히 페이지 폴드는 적을 것이다.
극단적인 반대 예로 프레임이 하나밖에 없는 경우는 페이지를 참조할 때마다 페이지 폴트가 발생할 것이다.
그렇기 때문에 메모리가 작은 컴퓨터에 비해 메모리가 큰 컴퓨터가 성능이 더 좋다고 하는 것이다.
이처럼 프로세스가 실행되는 시간보다 페이징에 더 많은 시간을 소요하여 성능이 저해되는 문제를 스레싱이라고 부른다.
이 말은 실행되는 프로세스 수를 늘린다고 CPU 이용률이 높아지는 것이 아니다 라는 것이다.
스레싱이 발생되는 근본적인 이유
- 각 프로세스가 필요로 하는 최소한의 프레임 수가 보장되지 않기 때문
- 그렇기에 각 프로세스가 필요로 하는 최소한의 프레임 수를 파악하고 프로세스에게 적절한 프레임을 할당해야한다.
- ex) 어떤 프로세스가 무리 없이 실행되기 위해 최소 10개의 프레임이 필요한데 5개만 할당되면 당연하게 페이지 폴트가 자주 발생하고 스레싱이 일어날 것이다.
운영체제의 프레임 할당 방법
균등 할당
가장 단순하다. 말그대로 모든 프로세스에게 균등하게 프레임을 할당 시키는 방식이다.
현재 300개의 프레임을 할당할 수 있고 3개의 프로세스가 있다면 각각 100개를 할당해주는게 균등 할당이다.
권장할만한 방법은 아니다. 실행되는 프로세스의 크기는 각기 다르기 때문이다.
비례 할당
프로세스의 크기를 고려해서 프레임을 할당 시키는 방식이다.
균등 할당과 비례 할당은 프로세스의 실행 과정을 고려하지 않고 단순히 프로세스의 크기나 물리 메모리의 크기만을 고려하는 방식으로 정적 할당 방식이라고 부른다.
비례 할당도 효과적인 방법은 아니다.
막상 실행을 해보니 많은 프레임을 필요로 하지 않을 수도 있다.
반대로 작은 프로세스인데 실행을 해보니 많은 프레임을 필요로 할 수도 있다.
결국 실행을 해봐야 아는 것이다.
정적 할당 방식
그래서 실행 타이밍에서 보고서 할당하는 방식이 있다.
작업 집합 모델
프로세스가 실행하는 과정에서 배분할 프레임을 결정한다.
CPU가 특정 시간 동안 주로 참조한 페이지 개수 만큼만 프레임을 할당한다.
작업 집합을 구하는 방법
- 프로세스가 참조한 페이지
- 시간 간격이 필요하다.

참조 페이지가 위와 같고 시간 간격이 7이라고 생각해보자

최소 5 6 7 이라는 3개의 프레임이 t1의 순간에 필요하다.
페이지 폴트 빈도 기반 프레임할당
프로세스가 실행하는 과정에서 배분할 프레임을 결정한다.
두개의 가정에서 생겨난 아이디어이다.
- 페이지 폴트율이 너무 높으면 그 프로세스는 너무 적은 프레임을 가지고있다.
- 페이지 폴트율이 너무 낮으면 그 프로세스는 너무 많은 프레임을 가지고 있다.

페이지 폴트율의 상한선과 하한선의 기준을 정하고 범위 안에서만 프레임을 할당하는 방식이다.
이렇게 프로세스가 실행하는 과정을 관찰하면서 프레임을 할당하기 때문에 동적 할당 방식이라고 부른다.