본문 바로가기
@9ky02025. 10. 17. 18:24

0. 들어가며

CPU와 프로세스가 메모리 몇 번지에 무엇이 저장되어 있는지 모두 알고 있을 거라 생각할 수도 있다. 하지만 실제로 그렇지 않다. 왜냐하면 이러한 번지를 다 알기 위해서는 CPU 내부의 저장공간(레지스터)이 메모리만큼 커야 할 텐데, 실제로는 그보다 훨씬 작은 용량을 갖고 있기 때문이다. 게다가 새로운 프로세스는 새롭게 메모리에 적재되고, 사용되지 않는 프로세스는 메모리에서 삭제된다. 메모리 정보는 시시때때로 변경될 수 있다는 의미이다. 메모리에 적재된 모든 프로세스와 CPU가 이렇게 실시간으로 바뀌는 정보를 모두 기억하기는 어렵다. 그렇다면 CPU는 어떻게 메모리에 적재된 프로세스의 주소를 인식하고 관리할까?

1. 물리 주소와 논리 주소

CPU와 프로세스는 메모리 하드웨어 상 실제 주소인 물리 주소(physical address)가 아닌 논리 주소(logical address)를 이용한다. 논리 주소는 프로세스마다 부여되는 0번지부터 시작하는 추소 체계로, 가령 현재 메모리 상에 웹 브라우저, 메모장, 게임 프로세스가 적재되어 있다면 이 모든 프로세스에는 0번지부터 시작하는 각자의 논리 주소를 가지고 있는 셈이다.

 

CPU와 프로세스가 사용하는 주소 체계는 물리 주소가 아니라 논리 주소이기 때문에 중복되는 물리 주소의 번지수는 존재하지 않지만, 중복되는 논리 주소의 번지수는 얼마든지 존재할 수 있다. 하지만 논리 주소라 할지라도 실제로 정보가 저장되어 있는 하드웨어 상의 메모리와 상호작용하기 위해서는 반드시 논리 주소와 물리 주소 간의 변환이 이루어져야 한다. 이를 위해 존재하는 하드웨어가 바로 메모리 관리 장치(MMU: Memory Management Unit)이다. MMU는 CPU와 메모리 사이에 위치하며, CPU가 이해하는 논리 주소를 메모리가 이해하는 물리 주소로 변환하는 역할을 한다.

2. 스와핑과 연속 메모리 할당

프로세스가 메모리에 할당되는 가장 기본적인 방식으로 스와핑과 연속 메모리 할당이 있다.

1. 스와핑

메모리에 적재된 프로세스들 중에는 현재 실행되고 있지 않은 프로세스도 있을 수 있다. 입출력 작업을 요구해 대기(Blocked) 상태가 되었거나 오랫동안 사용되지 않은 프로세스가 이러한 프로세스에 해당하는데, 이들을 임시로 스왑 영역(swap space)이라는 보조기억장치의 일부인 영역으로 쫓아내고, 프로세스를 쫓아낸 자리에 생긴 메모리 상 빈 공간에 다른 프로세스를 적재하여 실행하는 메모리 관리 방식을 스와핑(swapping)이라고 한다.

시스템 속성에서 스왑 영역(Windows에서는 페이징 파일) 크기 확인 가능

현재 실행되지 않는 프로세스가 메모리에서 스왑 영역으로 옮겨지는 것을 스왑 아웃(swap-out), 반대로 스왑 영역에 있는 프로세스가 다시 메모리로 옮겨오는 것을 스왑 인(swap-in)이라고 하는데, 스왑 아웃 되었던 프로세스가 다시 스왑 인 될 때는 스왑 아웃되기 전의 물리 주소와 다른 주소에 적재될 수 있다.

2. 연속 메모리 할당과 외부 단편화

운영체제는 스와핑이라는 기본적인 메모리 관리 기법을 통해 프로세스들을 메모리 내 빈 공간에 적재한다. 그런데 만약 메모리 내 빈 공간이 여러 개라면 어디에 프로세스를 배치해야 할까?

 

지금까지는 메모리 내에 프로세스들이 연속적으로 배치되는 상황을 가정했다. 그림과 같이 프로세스 A는 A의 크기만큼 메모리 주소를 할당받아 배치되고, 프로세스 B는 프로세스 A 이후에 B의 크기만큼 연속적으로 메모리 주소를 할당받아 배치되는 식이다. 이렇게 프로세스에 연속적인 메모리 공간을 할당하는 방식을 연속 메모리 할당이라고 한다.

언뜻 보기에는 당연하다고 생각할 수 있지만, 사실 연속 메모리 할당은 메모리를 효율적으로 사용하는 방법은 아니다. 외부 단편화라는 문제를 내포하고 있기 때문이다. 다음 그림과 같은 상황을 가정해 보자. 메모리에 새로운 프로세스가 적재될 수 있는 빈 공간의 총합은 50MB인데, 남아있는 공간이 각각 30MB, 20MB라 크기가 50MB인 프로세스를 적재할 수 없다.

이처럼 프로세스들이 메모리에 연속적으로 할당되는 환경에서는 프로세스의 실행과 종료를 반복하며 메모리 사이사이에 빈 공간이 생긴다. 프로세스 바깥에 생기는 빈 공간들은 분명 빈 공간이 맞지만 그보다 큰 프로세스를 적재하기 어려운 상황을 초래하고, 이는 메모리 낭비로 이어진다. 이러한 현상을 외부 단편화(external fragmentation)라고 한다.

이전 포스팅 [Stack 메모리 vs Heap 메모리]에서 외부 단편화를 다루었다. 궁금한 사람은 해당 게시글을 참고해 봐도 좋겠다.

3. 페이징을 통한 가상 메모리 관리

스와핑과 연속 메모리 할당은 2가지 문제를 내포한다. 하나는 위에서 살펴본 외부 단편화이고, 또 하나는 물리 메모리보다 큰 프로세스를 실행할 수 없다는 문제다. 프로세스를 반드시 연속적으로 메모리에 할당해야 한다면 메모리보다 큰 프로그램은 적재할 수 없다. 4GB 메모리 컴퓨터로는 4GB 이상의 프로그램을 실행할 수 없는 것처럼 말이다.

이러한 문제를 해결하기 위해 운영체제는 가상 메모리(virtual memory)라는 메모리 관리 기법을 사용한다. 실행하고자 하는 프로그램의 일부만 메모리에 적재해, 실제 메모리보다 더 큰 프로세스를 실행할 수 있도록 만드는 메모리 관리 기법으로, 보조기억장치의 일부를 메모리처럼 사용하거나 프로세스의 일부만 메모리에 적재함으로써 메모리를 실제 크기보다 더 크게 보이게 하는 기술이다.

1. 페이징: Paging

대표적인 가상 메모리 관리 기법에는 페이징과 세그멘테이션이 있다. 여기서는 Windows를 비롯해 많은 운영체제에서 범용적으로 사용되는 페이징 기법에 대해 알아보자.

 

프로세스의 논리 주소 공간을 페이지(Page)라는 일정한 단위로 나누고, 물리 주소 공간을 페이지와 동일한 크기의 프레임(frame)이라는 일정한 단위로 나눈 뒤 페이지를 프레임에 할당하는 가상 메모리 관리 기법이다. 이때, 프로세스를 구성하는 페이지는 물리메모리 내에 불연속적으로 배치될 수 있다.

이와 같이 메모리를 할당하면 외부 단편화가 발생하지 않는다. 페이지라는 일정한 크기로 잘린 프로세스들을 메모리에 불연속적으로 할당하기 때문에, 연속 메모리 할당처럼 프로세스 바깥에 빈 공간이 생길 수 없기 때문이다.

 

페이징 기법에도 스와핑이 사용될 수 있다. 대신 프로세스 전체가 스왑 아웃/인 되는 것이 아닌 페이지 단위로 이루어진다. 페이징 시스템에서의 스왑 아웃은 페이지 아웃(page out), 스왑 인은 페이지 인(page in)이라고 부른다.

 

가령 같은 프로세스를 이루는 페이지 중 일부는 페이지 인 되고, 일부는 페이지 아웃 되었다고 가정해 보자. 즉 프로세스 일부는 메모리에 적재되고, 일부는 보조기억장치에 적재되었다는 것을 의미하며, 이는 프로세스 실행을 위해 전체 프로세스가 메모리에 적재될 필요가 없음을 의미한다. CPU 입장에서 바라본 논리 메모리의 크기가 실제 메모리 크기보다 클 수 있다는 뜻이다. 페이징을 통해 물리 메모리보다 큰 크기의 프로세스 실행도 가능해진 것이다.

참고: 세그멘테이션(Segmentation)

세그멘테이션은 프로세스를 일정한 크기의 페이지 단위가 아닌 세그먼트(segment)라는 가변 크기 단위로 분할하는 방식이다. 다음 그림처럼 논리적 단위로 분할하는 방식으로, 하나의 세그먼트는 코드 영역(내지 일부) 일 수도 있고 데이터 영역(내지 일부) 일 수도 있다. 세그먼트의 크기가 일정하지 않기 때문에 외부 단편화가 발생할 수 있다.

2. 페이지 테이블

프로세스를 구성하는 페이지는 물리 메모리 내에 불연속적으로 배치될 수 있는데, CPU 입장에서는 다음으로 실행할 페이지의 위치를 찾기 어렵다. CPU가 프로세스를 이루는 어떤 페이지가 어떤 프레임에 적재되어 있는지를 모두 알고 있기 어렵기 때문이다.

 

이러한 문제를 해결하기 위해 프로세스의 페이지와 실제로 적재된 프레임을 짝지어주는 페이지 테이블(page table)을 활용한다. 테이블에는 페이지 번호와 실제로 적재된 프레임 번호가 대응되어 있기 때문에, CPU는 페이지 번호만 보고도 적재된 프레임을 찾을 수 있다. 프로세스마다 각자의 페이지 테이블 정보를 갖고 있어, CPU가 서로 다른 프로세스를 실행할 때는 각 프로세스의 페이지 테이블을 참조하여 메모리에 접근한다.

페이지 테이블은 기본적으로 페이지 번호와 그에 대응되는 프레임 번호로 구성되어 있는데, 여기에 추가로 다른 중요한 정보들이 포함되어 있다. 테이블을 구성하는 각 행들을 테이블 엔트리(PTE: Page Table Entry)라 하는데, OS마다 차이는 있지만 보통 페이지 번호 / 프레임 번호 / 유효 비트 / 보호 비트 / 참조 비트 / 수정 비트는 포함된다.

유효 비트(valid bit)는 해당 페이지에 접근 가능한지 여부를 알려주는 정보로, 현재 페이지가 메모리에 있는지 아니면 보조기억장치에 있는지 알려주는 비트이다. 유효 비트는 페이지가 메모리에 적재되어 있다면 1, 아니라면 0이 된다. CPU는 보조기억장치에 저장된 페이지에 곧장 접근할 수 없으므로 보조기억장치에 저장된 페이지에 접근하려면 우선 해당 페이지를 메모리에 적재한 뒤에 접근해야 한다. 만약 CPU가 메모리에 적재되지 않은 페이지, 즉 유효 비트가 0인 페이지에 접근하려고 하면 페이지 폴트(page fault)라는 예외(Exception)가 발생한다.

Windows의 경우 리소스 모니터에서 현재 처리하고 있는 페이지 폴트를 확인할 수 있다.

CPU의 페이지 폴트 처리 과정은 다음과 같다.

  1. 기존 작업 내역을 백업한다.
  2. 필요한 페이지를 메모리로 가져와 유효 비트를 1로 변경하는 페이지 폴트 처리 루틴을 실행한다.
  3. 루틴 실행 후 메모리에 적재된 페이지를 실행한다.

보호 비트(protection bit)는 페이지 보호 기능을 위해 존재하는 비트이다. 읽기(r), 쓰기(w), 실행(x)을 조합해 페이지에 접근할 권한을 제한함으로써 페이지를 보호할 수 있다. 가령 보호 비트가 100으로 설정된 페이지는 r = 1, w = 0, x = 0으로 읽기만 가능하고, 보호 비트가 111로 설정된 페이지는 읽기, 쓰기, 실행이 모두 가능하다.

이전에 작성한 글 중 [C++ 메모리 관리 기법 - Custom Allocator]에서 OS로부터 할당받은 페이지의 보안 정책을 코드로 적용해 보았다. 궁금한 사람은 해당 게시글을 참고해도 좋겠다.

 

참조 비트(reference bit)는 CPU가 해당 페이지에 접근한 적 있는지를 나타내는 비트이다. 페이지에 적재한 이후에 CPU가 읽거나 쓴 페이지는 1로 설정되고, 한 번도 읽거나 쓴 적이 없는 페이지는 0으로 유지된다.

 

수정 비트(modified bit)는 해당 페이지에 데이터를 쓴 적이 있는지를 알려주는 비트로, 더티 비트(dirty bit)라 부르기도 한다. 비트가 1이면 변경된 적이 있는 페이지이고, 0이면 변경된 적이 없는(한 번도 접근한 적이 없거나 읽기만 했던) 페이지임을 나타낸다. 한 번이라도 페이지에 쓰기 작업을 한 경우에는 페이지를 메모리에서 삭제해야 할 때 페이지의 수정 내역을 보조기억장치에도 반영해 두어야 하므로 보조기억장치에 대한 쓰기 작업이 필요하다. 반대로 수정한 적이 없다면 보조기억장치에 반영할 내역이 없으므로 별도의 쓰기 작업 없이 페이지를 메모리에서 삭제하기만 해도 된다.

 

페이징은 외부 단편화 문제를 해결할 수 있지만, 내부 단편화 문제가 여전히 남아있다. 모든 프로세스가 페이지 크기에 딱 맞게 잘리지 않기 때문이다. 가령 페이지 크기는 10KB인데 프로세스 크기가 107KB인 경우, 마지막 페이지는 3KB만큼 남는다. 이렇게 페이지 하나의 크기보다 작은 크기로 발생하게 되는 메모리 낭비가 내부 단편화(internal fragmentation)이다.

각 프로세스의 페이지 테이블은 메모리에 적재될 수 있다. 따라서 어떤 프로세스를 실행하려면 이 프로세스의 페이지 테이블이 메모리에 적재된 위치를 알아야 하는데, 페이지 테이블 베이스 레지스터(PTBR: Page Table Base Register)가 테이블이 적재된 메모리 상의 위치를 가리킨다. PTBR은 프로세스마다 가지는 정보이므로 각 PCB에 기록되며, 다른 프로세스로의 컨텍스트 스위칭이 발생할 때 변경된다.

페이지 테이블이 메모리에 적재될 수 있지만 운영체제는 모든 페이지 테이블을 메모리에 적재하는 것을 가급적 지양한다.

 

첫 번째 이유는 메모리 접근 횟수가 많아지기 때문이다. 모든 프로세스의 페이지 테이블이 메모리에 적재되어 있을 경우, CPU는 페이지 테이블에 접근하기 위해 한 번, 실제 프레임에 접근하기 위해 한 번, 이렇게 총 두 번 메모리에 접근해야 한다. 따라서 메모리에 접근하는 시간이 두 배로 늘어날 수 있다. 이를 해결하기 위해 TLB(Transiation Look-aside Buffer)라는 페이지 테이블의 캐시 메모리를 사용한다. TLB는 페이지 테이블의 캐시이므로 참조 지역성 원리에 근거해 자주 사용할 법한 페이지 위주로 테이블의 일부 내용을 저장한다.

 

CPU가 접근하려는 논리 주소의 페이지 번호가 TLB에 있을 경우 TLB는 CPU에게 해당 페이지 번호가 적재된 프레임 번호를 알려준다. 이를 TLB Hit이라 한다. 이 경우에는 한 번만 메모리에 접근하면 된다. 하지만 페이지 번호가 TLB에 없는 경우 어쩔 수 없이 페이지가 적재된 프레임을 알기 위해 메모리 내의 페이지 테이블에 접근해야 한다. 이를 TLB Miss라고 한다. TLB 미스의 경우 추가적인 메모리 접근이 필요하다. 즉, 메모리 접근 횟수를 낮추려면 TLB Hit Ratio를 높여야 한다.

두 번째 이유로는 페이지 테이블이 메모리 용량을 많이 차지하기 때문이다. 페이지 테이블의 크기는 생각보다 작지 않다. 프로세스의 크기가 커지면 자연히 페이지 테이블의 크기도 커지기 때문에 프로세스를 이루는 모든 페이지 테이블 엔트리들을 메모리에 두는 것은 아무래도 부담스럽다. 그래서 등장한 방법 중 하나가 계층적 페이징(hierarchical paging)으로, 페이지 테이블을 페이징 한다. 여러 단계의 페이지를 둔다는 점에서 다단계 페이지 테이블(multilevel page table) 기법이라고도 부른다.

 

가령 한 프로세스의 페이지 테이블이 다음과 같다고 가정해 보자. 계층적 페이징 기법을 사용하지 않으면 페이지 테이블 전체가 메모리에 적재되어 있어야 한다.

계층적 페이징은 다음 그림처럼 프로세스의 페이지 테이블을 여러 개의 페이지로 자르고, CPU와 가까이 위치한 바깥쪽에 Outer 페이지 테이블을 하나 더 두어 잘린 페이지 테이블의 페이지들을 가리키게 한다. 이렇게 계층 구조를 구성하면 모든 페이지테이블을 항상 메모리에 유지할 필요가 없어진다. Outer 페이지 테이블만 메모리에 유지하면 잘린 페이지 테이블의 일부가 보조기억장치에 있더라도 Outer 페이지 테이블을 통해 언제든 접근할 수 있기 때문이다.

2개의 계층으로 구성. 3개 이상으로도 구성될 수 있음

3. 페이징 주소 체계

하나의 페이지 내에는 여러 주소가 포함되어 있기 때문에 페이징 시스템의 논리 주소는 기본적으로 <페이지 번호, 오프셋> 형태로 이루어져 있다. 페이지 번호(page number)는 몇 번째 페이지 번호에 접근할지를 나타내며, 테이블을 참조하면 물리 메모리 내 어떤 프레임에 접근할지를 알 수 있다. 오프셋(offset)은 접근하려는 주소가 페이지(프레임) 시작 번지로부터 얼마만큼 떨어져 있는지를 나타낸다. 즉 <페이지 번호, 오프셋>으로 이루어진 논리 주소가 페이지 테이블을 통해 물리 주소 <프레임 번호, 오프셋>으로 변환된다.

 

예를 들어 현재 CPU와 페이지 테이블, 메모리 상태가 다음 그림과 같다고 해보자. 만약 CPU가 논리 주소 <5, 2>에 접근한다면, CPU가 실제로 접근하게 될 물리 주소는 그림의 페이지 테이블에서 1번 프레임에 있으므로 물리 주소 <1, 2>에 접근하게 된다. 1번 프레임은 물리 주소 공간의 8번지부터 시작하므로 결국 CPU는 10번지에 접근하게 되는 것이다.

4. 페이지 교체 알고리즘

프로세스를 이루는 모든 페이지가 메모리에 적재되지 않아도 되는 만큼, 필요한 페이지만 메모리에 적재하면 더 좋을 것이다. 이를 가능케 하는 기법을 요구 페이징(demand paging)이라 한다. 요구 페이징의 기본적인 양상은 다음과 같다.

  1. CPU가 특정 페이지에 접근하는 명령어를 실행한다.
  2. 해당 페이지가 현재 메모리에 있으면(유효 비트 1) CPU는 페이지가 적재된 프레임에 접근한다.
  3. 해당 페이지가 현재 메모리에 없다면(유효 비트 0) 페이지 폴트가 발생한다.
  4. 페이지 폴트가 발생하면 처리 루틴을 통해 해당 페이지를 메모리에 적재하고 유효 비트를 1로 설정한다.
  5. 1의 과정을 다시 수행한다.
참고로 아무런 페이지도 메모리에 적재하지 않고 프로세스를 실행할 수도 있다. 이를 순수 요구 페이징(pure demand paging)이라 하는데, 첫 명령어를 실행하는 순간부터 페이지 폴트가 발생하고, 페이지가 어느 정도 적재된 이후부터 페이지 폴트 발생 빈도가 떨어진다. 

 

이때 요구 페이징을 통해 페이지들을 메모리에 점차 적재하다 보면 언젠가는 메모리에 가득 찰 것이다. 메모리에 페이지가 가득 찬 상황에서 추가적으로 페이지를 적재해야 한다면 기존 페이지를 일부 스왑 아웃해야 한다. 이때 메모리에 적재된 페이지 중 보조기억장치로 내보낼 페이지를 선택하는 방법을 페이지 교체 알고리즘(page replacement algorithm)이라고 한다.

 

페이지 교체 알고리즘은 컴퓨터 전체 성능과도 직결된다. 어떤 알고리즘이 사용되냐에 따라 페이지 폴트 발생 빈도가 달라지기 때문인데, 좋은 알고리즘은 메모리에서 사용되지 않을 페이지를 적절하게 보조기억장치로 내보내기 때문에 페이지 폴트 발생 빈도가 적지만 나쁜 알고리즘은 곧 사용될 페이지를 내보내 페이지 폴트를 자주 발생시킬 수 있다. 빈번한 페이지 폴트의 발생은 보조기억장치로부터 필요한 페이지를 가져와야 하는 시간만큼 성능 저하를 가져온다.

 

알고리즘에는 여러 종류가 있는데, 대표적인 것 3개만 확인해 보자.

  1. FIFO(First-In First-Out) 페이지 교체 알고리즘: 메모리에 가장 먼저 적재된 페이지부터 스왑 아웃하는 알고리즘이다. 아이디어와 구현은 간단하지만, 초기에 적재되어 줄곧 참조되고 있는 페이지를 스왑 아웃할 우려가 있다. 이 경우 머지않아 페이지 폴트가 발생할 것이다.
  2. 최적(Optimal) 페이지 교체 알고리즘: 앞으로의 사용 빈도가 가장 낮은 페이지를 교체하는 알고리즘이다. 가장 적게 사용할 페이지를 스왑 아웃해 가장 낮은 페이지 폴트율을 보장하는 알고리즘이라 이름 그대로 '최적'이지만, '앞으로 가장 적에 사용할 페이지'를 미리 예측하기 어렵기 때문에 실제 구현이 어려운 알고리즘이다.
  3. LRU(Least Recently Used) 페이지 교체 알고리즘: 가장 적게 '사용한' 페이지를 교체하는 알고리즘이다. 보편적으로 사용되는 페이지 교체 알고리즘들의 원형이며, 이를 기반으로 만들어진 다양한 파생 알고리즘이 존재한다. 

참고 1: 스래싱(thrashing)

지나친 페이지 교체가 발생해 프로세스가 실제로 실행되는 시간보다 페이징에 더 많은 시간을 소요하여 성능이 저하되는 문제를 스래싱이라 한다. 보통 메모리에 올라온 프로세스 수가 너무 많아 각 프로세스가 필요한 최소한의 페이지를 확보하지 못했거나, 하나의 프로세스가 실행 도중 계속 페이지 폴트를 내며 다른 프로세스의 페이지를 밀어내 페이지 교체가 너무 자주 일어날 때 발생한다. 즉 CPU 이용률이 일정 수준까지는 올라가다가, 프로세스가 너무 많아지면 오히려 급격히 떨어지는 구간이 생기는데 해당 구간이 스래싱이 발생한 시점이다.

출처: https://charles098.tistory.com/117

스래싱 현상을 방지하거나 해결하기 위해 보통 작업 집합(Working Set) 모델이나 페이지 폴트 빈도 제어(PFF: Page Fault Frequency) 방식을 적용한다.

  1. Working Set 모델은 "자주 사용하는 페이지 집합을 계속 메모리에 유지하자"라는 아이디어로, 프로세스가 일정 시간 동안 실제로 참조하는 페이지 집합을 추적해 각 프로세스가 자신의 작업 집합 크기만큼의 프레임을 항상 확보하도록 관리하는 모델이다. 만약 전체 메모리보다 모든 프로세스의 작업 집합이 크다면 일부 프로세스를 스왑 아웃 시켜 메모리를 확보한다.
  2. PFF 방식은 "페이지 폴트율(Page Fault Rate)을 일정 범위를 유지하도록 프레임 수를 조절하자"라는 아이디어로, 프로세스의 페이지 폴트율(Page Fault Rate)을 모니터링해서 동적으로 프레임 수를 조절하는 방식이다. 만약 폴트율이 높으면 프레임을 추가로 할당하고, 폴트율이 낮으면 프레임을 회수한다. 이런 식으로 폴트율을 일정한 범위 안으로 유지하도록 한다.

이외에도 프로세스 수가 너무 많다면 일부를 스왑 아웃 시키든지, 프로세스에 우선순위를 매겨 중요도가 높은 프로세스에 더 많은 프레임을 배정한다든지, LRU와 같이 참조 지역성을 잘 반영한 페이지 교체 알고리즘을 적용해서 불필요한 교체를 줄이는 방법도 있다.

참고 2: 페이지 폴트의 종류

페이지 폴트에도 여러 종류가 있다. 보조기억장치와의 입출력 작업이 필요하냐 필요하지 않냐에 따라 크게 메이저 페이지 폴트와 마이너 페이지 폴트로 구분한다.

  1. 메이저 페이지 폴트(major page fault): 보조기억장치에서 CPU가 원하는 페이지를 읽어 들이기 위해 입출력 작업이 필요한 페이지 폴트이다. 앞서 설명한 페이지 폴트들이 이 유형이며, CPU가 접근하려는 페이지가 물리 메모리에 없을 때 발생하는 페이지 폴트로 볼 수 있다.
  2. 마이너 페이지 폴트(minor page fault): 보조기억장치와의 입출력이 필요하지 않은 페이지 폴트이다. CPU가 요청한 페이지가 물리 메모리에는 존재하지만, 페이지 테이블 상에는 반영되지 않은 경우에 발생할 수 있다. 일반적으로 메이저 페이지 폴트에 비해 성능 상 악영향이 적은 페이지 폴트이다.

5. 나가며

이것으로 운영체제의 가장 핵심적인 기능 중 하나인 가상 메모리와 관련된 내용을 전반적으로 정리해보았다. 원래는 멀티 프로세스/스레드 환경에서 데이터 동기화에 관한 내용을 먼저 정리해보려 했는데, [Stack 메모리 vs Heap 메모리] 게시글에 이어서 메모리 관련으로 얘기를 더 해보고자 가상 메모리 주제를 먼저 작성했다.

'Computer Science > Operating System' 카테고리의 다른 글

프로세스와 스레드  (3) 2025.10.13
Stack 메모리 vs Heap 메모리  (0) 2025.09.25
운영체제의 큰 그림  (0) 2025.05.09
9ky0
@9ky0 :: Hello, 9ky0!

공감하셨다면 ❤️ 구독도 환영합니다! 🤗

목차