앞서 본 논리주소를 물리주소로 변경하는 것은 하드웨어가 담당한다. 물리적메모리의 주소변환에 운영체제가 관여하지 않는다.
단, 가상메모리는 운영체제가 관여한다.
프로세스가 실행되기 위해서는 메모리에 프로세스가 올라가야한다. 하나의 프로세스가 메모리에 올라가게되면 많은 메모리를 차지하게 된다. 또한 올라간 프로세스는 코드 중에서도 특정 부분만 사용되고, 특정 시기에만 사용되다보니 프로세스의 모든 부분이 올라가 있는 것은 비효율적이다.
또한 메모리보다 큰 용량의 프로세스의 경우 메모리에 올라가는 것 자체가 불가능했다.
이러한 점들을 보완하고 물리적 메모리 크기의 한계를 극복하고자 등장한 것이 가상메모리이다.
가상메모리는 실제로 이용가능한 자원을 추상화하여 사용자들에게 매우 큰 메모리로 보이게 하는 기술을 말한다. 앞서 언급했던 것처럼 메모리에 로드되어도, 프로세스의 코드 중에서 일부만 사용된다고 했다. 그러니 일부가 사용되어질 때만 메모리에 올리고, 나머지 부분은 디스크에 나두는 것이다.
이는 프로그램의 전체가 물리적 메모리에 올라와 있는 것처럼 수행되어지는 것이다.
이렇게 프로그램이 실행되면서 필요한 순간 메모리에 올리고, 아닌 경우는 디스크에 두는 수행을 하는 것을 운영체제가 담당한다.
운영체제는 Demand paging이라는 것을 통해서 필요한 경우 데이터를 올리고 아닌 경우 다시 디스크로 되돌린다.
요청이 있으면 프로세스의 page를 메모리에 올리는 것이다.
(페이징기법을 사용한다는 가정하며, 실제 많은 시스템이 페이징기법을 사용하고 있다.)
페이징기법은 프로그램이 실행될 때 프로세스를 구성하는 주소공간의 페이지를 한번에 올리는 것이 아니라 demand paging기법을 사용한다. 페이지가 요청이 오면 메모리에 올린다.
필요한 것만 메모리에 올리기 때문에 I/O양이 감소하고,
Memory 사용량이 감소하고 빠른 응답이 가능하다.
더많은 프로세스를 올릴 수 있다.(멀티프로세스의 경우)
한정된 메모리공간을 더 잘 사용할 수 있다.
페이지테이블에 vaild 와 invaild bit을 이용해서 페이지가 물리적 메모리에 있는지 아닌 지를 확인한다. 페이지가 페이지프레임에 없다면 page fault가 난다.
맨 오른쪽에 둥근것이 swap area, back store이다.
프로그램을 구성하는 페이지 중에서 당장 필요한 부분은 demand paging에 의해서 물리적메모리에 올라가 있을 것이고, 그렇지 않는 부분은 back store에 내려가 있게 된다.
페이지테이블의 invalid의 의미는 물리적메모리에 없는 경우를 의미하다.
프로그램을 구성하는 페이지는 a-f까지 이다. g,h는 사용되지 않는 페이지 이지만, 주소공간만큼 페이지 테이블이 있기 때문에 사용되지 않는 페이지에 대해서도 페이지테이블에 자리가 있어야 한다. 그리고 그 부분은 invalid로 표현을 해야 한다.
swap area에 내려가있는 경우도 invaild로 표현된다.
주소변환으로 물리적인 페이지프레임 값을 얻을 수 있는 경우만 vaild로 표현된다.
demand paging을 사용하기 때문에 처음 프로그램이 실행되면 모든 페이지테이블이 invaild로 존재하다가 페이지가 메모리에 올라가면 invaild에서 vaild로 바뀌게 된다.
주소변환을 하려는데 invaild로 표시된 페이지에 대해서는 page fault가발생한다.
요청한 페이지가 메모리에 없는 경우를 의미한다.
요청한 페이지는 디스크 영역에 있고, 이를 가지고 오는 것은 I/O작업에 해당하기 때문에 운영체제가 처리해야하는 작업이다. 그렇기 때문에 운영체제에 cpu를 넘기게 된다.
cpu는 자동적으로 운영체제에 넘어가게된다. page fault트랩이 발생한다.
운영체제가 cpu를 가지고 fault난 페이지를 메모리에 올리는 작업이 필요하다.
주소변환을 해주는 하드웨어(MMU)가 트랩을 발생시킨다. 그러면 cpu제어권이 운영체제로 넘어가고 운영체제에서 page fault를 처리하는 함수를 실행하게 된다.
디스크에서 메모리를 가지고 오는 작업은 매우 느린작업이다.
디스크I/O를 하게 되면, 프로세스가 cpu를 가지고 있어봐야 cpu낭비가 발생하므로, cpu를 뺏어서 이 프로세스는 block으로 처리하고, 다른 ready상태의 프로세스에게 cpu를 넘기게 된다.
디스크 I/O가 끝나게 되면, 인터럽트를 걸어서 페이지폴트 작업이 끝났다는 것을 운영체제가 알아서 다시 cpu를 잡게 되면 메모리 주소전환이 정상적으로 진행될수 있다.
페이지 폴트가 발생했을 때 디스크에 접근해서 I/O작업을 하는 것은 굉장히 오래걸리기 때문에 페이지폴트가 얼마나 나는냐에 따라서 메모리 접근하는 시간이 많이 차이가 난다.
그러므로 페이지 폴트가 최대한 적게 발생하는 것이 효율적 측면에서 좋다.
프로세스에서 새로운 페이지가 필요해서 페이지를 물리적 메모리에 올리려는데, 물리적메모리가 이미 꽉차있는 상태이다. 그렇다면 어떻게 해야 할까?
빈프레임이 없으면 운영체제가 쫒아내고 다른 것을 올려야 한다.
page replacement는 말 그대로 물리적메모리에 있는 페이지를 쫒아내는 것이다. 단, 쫒아내기전에 해당 페이지에 의해 변경된 내용이 있다면 back store에 다시 써주어야 한다. 그렇지 않으면 변경된 내용이 적용이 되지 않게된다.
변경된 내용이 없다면 물리적메모리에서 지우면된다.(back store에는 모든 페이지의 공간이 존재한다.)
어떤알고리즘으로 교체를 해야 가장 좋을까?
페이지폴트를 가장 적게하는 알고리즘이다.
미래에 참조되어지는 페이지를 알고서 참조가 가장 늦게 되는 것을 변경하는 알고리즘이다. 하지만 시스템에서는 미래의 상황을 알 수 없기 때문에, 불가능한 알고리즘이다. 미래의 참조되는 page를 모두 안다는 가정하에 진행되는 알고리즘이다. 가장 이상적인 방법일 뿐이다.
optimal알고리즘이 알려주는 것은 optimal 알고리즘 보다 적게 페이지폴트를 적게 나올수는 없다. 그러므로 optimal 알고리즘과 비슷한 성능에서 페이지폴트가 발생하는 알고리즘이 좋은 알고리즘이라는 기준이 될 수 있다.
먼저 들어온 것을 먼저 내 쫒는다.
페이지프레임이 늘려도 성능이 나빠질 수도 있는 가능성이 있다.
FIFO Anomaly(페이지폴트의 수가 늘어난다)
가장 오래 전에 참조된 것을 지운다. 가장 오래전에 사용된 것을 바꾸는 방법이다. 들어온 기준이 아닌 사용된 것 기준으로 페이지를 쫒아낸다.
참조횟수가 적은 페이지를 메모리에서 쫒아낸다. 연결리스트를 이용해서 구현한다.
LRU알고리즘은 마지막 참조부분만 보기 때문에 과거의 참조 횟수와 같은 것은 고려하지 않는다. 그렇기 때문에 빈번히 사용 될 수도 있는 페이지가 교체될 가능성이 있다.
LFU알고리즘은 참조횟수를 고려하지만, 처음 참조된 경우라면 참조횟수가 적기 때문에 바뀌게 될 것이다.