1. 가상 메모리의 기본 개념
정의
가상 메모리는 프로그램이 사용하는 메모리 주소 공간을 물리적 메모리(RAM)와 별도로 관리하는 메모리 관리 기법입니다. 가상 메모리는 프로그램이 실제로 사용하는 것보다 더 많은 메모리 공간을 제공하도록 합니다. 따라서 여러 프로그램이 동시에 실행될 때, 각 프로그램은 별도의 메모리 공간을 가지며, 물리 메모리에 대한 직접적인 접근 없이도 실행될 수 있습니다.
필요성
가상 메모리는 다음과 같은 이유로 필요합니다:
메모리 보호: 서로 다른 프로세스가 자신의 메모리 공간을 보호할 수 있도록 하고, 하나의 프로세스가 다른 프로세스의 메모리에 접근하지 못하게 합니다.
메모리 확장: 실제 물리적 메모리보다 큰 주소 공간을 사용하여, 더 많은 프로그램과 데이터가 동시에 메모리에 올라갈 수 있게 합니다.
메모리 관리의 효율성: 필요한 데이터와 코드를 메모리에 불러오는 방식(예: 페이지 교체)을 통해 메모리의 활용도를 높입니다.
예시: 가상 메모리의 작동 방식
예시 시나리오
가령, 여러분이 여러 개의 프로그램을 동시에 실행하는 상황을 예로 들어보겠습니다. 예를 들어, 웹 브라우저와 텍스트 편집기를 동시에 실행한다고 가정합니다.
가상 주소 공간:
- 웹 브라우저는 약 4GB의 가상 주소 공간을 필요로 하고, 텍스트 편집기도 마찬가지로 4GB의 가상 주소 공간을 필요로 한다고 가정해보겠습니다.
- 각 프로그램은 가상 주소 0부터 시작하여 자신의 주소 공간을 사용합니다.
물리적 메모리 제한:
- 가정해 보건대 여러분의 컴퓨터에 실제 RAM은 8GB밖에 없습니다. 그렇다면 하나의 애플리케이션이 실행되면 총 메모리 사용량이 8GB를 초과하는 것이죠.
가상 메모리의 적용:
- 가상 메모리를 사용하면 두 프로그램은 각각 자신만의 가상 주소 공간을 가지지만, 실제로 물리적으로 메모리에 존재하는 것은 아닙니다.
- 웹 브라우저가
0x00000000
부터0xFFFFFFFF
(가상) 주소를 사용하고, 텍스트 편집기 역시 동일한 주소 범위를 사용할 수 있지만, 서로의 코드는 격리되어 있습니다.
페이지 테이블의 역할
- 각 프로그램이 메모리를 요청할 때, 운영체제는 해당 프로그램의 요청을 처리하기 위해 페이지 테이블을 사용합니다. 만약 프로그램이 특정 가상 주소를 참조하면:
- 운영체제는 해당 주소가 실제 물리 메모리에 로드되어 있는지 확인합니다.
- 물리 메모리 내에 존재하지 않는 경우, 페이지 결핍(Page Fault)이 발생하고, 운영체제는 해당 데이터를 디스크에서 불러와야 합니다.
- 페이지 결핍 사례:
- 웹 브라우저가 가상 주소
0x00001111
를 참조한다고 가정해 보겠습니다. 이 주소가 현재 물리 메모리에 존재하지 않으면 페이지 결핍이 발생합니다. - 운영체제는 디스크에서 이 데이터를 찾아서 물리 메모리에 로드하고 페이지 테이블을 업데이트하여 가상 주소
0x00001111
가 이제 물리 메모리의 특정 주소를 가리키도록 합니다.
- 웹 브라우저가 가상 주소
2. 페이지 테이블
정의
페이지 테이블은 운영체제가 가상 메모리 주소를 물리 메모리 주소로 변환하기 위해 사용하는 데이터 구조입니다. 페이지 테이블은 각 프로세스에 대해 존재하며, 해당 프로세스가 사용하는 가상 주소와 물리 주소의 매핑 정보를 저장합니다.
왜 필요한가?
- 주소 변환: 프로그램이 메모리에 접근할 때 사용하는 가상 주소는 실제 물리 주소와는 다릅니다. 페이지 테이블은 이 두 주소간의 변환을 관리합니다.
- 메모리 보호: 각 프로세스의 가상 주소 공간을 독립적으로 관리하기 때문에, 하나의 프로세스가 다른 프로세스의 메모리에 접근하지 못하게 합니다.
페이지와 프레임의 개념
페이지
- 가상 메모리의 단위로, 일반적으로 고정된 크기를 가지고 있습니다. 예를 들어, 4KB 크기의 페이지가 있을 수 있습니다.
프레임
- 물리 메모리(RAM)의 단위로, 페이지와 크기가 동일합니다. 즉, 하나의 프레임이 4KB 크기라면, 페이지도 4KB입니다.
페이지 테이블의 구조
페이지 테이블은 다음과 같은 정보를 포함합니다:
- 페이지 번호: 가상 주소의 페이지 번호.
- 프레임 번호: 해당 가상 페이지가 매핑되는 물리 메모리의 프레임 번호.
- 상태 비트: 페이지의 상태를 나타내는 여러 비트 (예를 들어, 존재 여부, 수정 여부 등).
페이지 테이블 예시
가상 메모리를 사용하는 경우, 다음과 같은 간단한 예시를 들어 보겠습니다:
메모리 크기:
- 가상 주소 공간: 16 페이지 (각 페이지 4KB)
- 물리 메모리: 8 프레임 (각 프레임 4KB)
페이지 변환의 과정
가상 주소 요청:
- 예를 들어, 프로그램이 가상 주소
0x0000C000
(가상 페이지 3의 주소)을 요청하면, 이 주소를 페이지 단위로 나누어 가상 페이지 번호를 얻습니다.0x0000C000
의 페이지 번호는 다음과 같이 계산됩니다:- 계산:
0x0000C000 / 4KB = 3
(즉, 페이지 3)
- 계산:
- 예를 들어, 프로그램이 가상 주소
페이지 테이블 조회:
- 운영체제는 페이지 테이블을 조회하여 가상 페이지 3이 물리 메모리에 매핑되어 있는지를 확인합니다. 위 테이블에 따르면, 페이지 3은 물리 메모리의 프레임 1에 존재합니다.
주소 변환:
- 페이지 번호에 해당하는 프레임 번호를 찾으면, 실제 물리 주소를 계산합니다:
- 물리 주소 = (프레임 번호 * 페이지 크기) + 오프셋
- 예: 만약
0x0000C000
의 오프셋이 0이기 때문에, 물리 주소는1 * 4KB + 0 = 0x00001000
입니다.
- 페이지 번호에 해당하는 프레임 번호를 찾으면, 실제 물리 주소를 계산합니다:
페이지 결핍(page fault)
- 만약 요청한 가상 페이지가 페이지 테이블에 존재하지 않는다면, 페이지 결핍이 발생합니다. 예를 들어, 위의 테이블에서 가상 페이지 6을 요청한다면 페이지 결핍이 발생하고, 운영체제는 페이지를 디스크에서 로드해야 합니다.
3. 페이지 교체 알고리즘
페이지 교체 알고리즘은 물리 메모리에 있는 페이지가 모두 사용 중일 때, 새로운 페이지를 물리 메모리에 올리기 위해 어떤 페이지를 제거할지를 결정하는 정책입니다. 페이지 교체는 메모리의 효율성을 유지하며, 페이지 결핍(Page Fault)의 수를 최소화하기 위해 중요합니다.
주요 페이지 교체 알고리즘
최소 최근 사용 (Least Recently Used, LRU):
LRU 알고리즘은 가장 오랫동안 사용되지 않은 페이지를 교체합니다. 이것은 과거에 접근한 패턴을 기반으로 결정되며, 과거에 사용된 적이 없는 페이지가 미래에도 사용될 가능성이 낮다는 원리에 기초합니다.
장점: 직관적이며, 실제 사용 패턴을 반영합니다.
단점: 구현이 복잡할 수 있으며, LRU를 정확하게 유지하기 위해 메모리 사용이 추가로 필요할 수 있습니다.
예시*: 만약 물리 메모리에 페이지 A, B, C가 있고 새로운 페이지 D를 로드하려고 할 때, 페이지 C가 가장 오래전 사용되었다면 C를 교체합니다.
선입선출 (First In First Out, FIFO):
FIFO 알고리즘은 가장 먼저 메모리에 로드된 페이지를 교체합니다. 이 알고리즘은 구현이 간단하지만, 주의가 필요합니다.
장점: 구현이 간단합니다.
단점: 자주 참조되지 않더라도 오랫동안 남아 있을 수 있는 페이지를 교체할 수 있어, 비효율적인 경우가 많습니다.
예시*: 페이지 A, B, C가 메모리에 있을 때 A가 가장 먼저 들어온 페이지라면, 새 페이지 D가 들어올 때 A를 교체합니다.
가장 덜 사용된 (Least Frequently Used, LFU):
LFU 알고리즘은 가장 적게 사용된 페이지를 교체합니다. 각 페이지 접근에 대해 카운터를 두고, 사용된 횟수를 기반으로 결정합니다.
장점: 적어도 한번도 사용되지 않은 페이지를 제거하기 때문에 나쁘지 않습니다.
단점: 카운터를 유지해야 하므로, 메모리 비용이 발생하고, 최근에 사용한 페이지라 하더라도 장기적으로 사용되지 않는 경우 제거될 수 있습니다.
예시*: 카운터가 1인 페이지 A, B, C가 있다면, 페이지 D를 로드하기 위해서 카운터가 가장 적은 페이지(예: A)를 교체합니다.
나중에 사용될 페이지 예측 (Optimal Page Replacement):
이 알고리즘은 가장 먼 미래에 사용될 페이지를 교체합니다. 이론적으로 최적의 알고리즘으로 간주되지만, 실제 구현은 불가능합니다. 미래의 요청을 알 수 없기 때문입니다.
장점: 이론적으로는 가장 효율적입니다.
단점: 실제로 구현할 수 없고 예측하려면 상대적으로 복잡한 분석이 필요합니다.
예시*: 만약 페이지 A, B, C가 메모리에 있다면, 페이지 D가 나중에 요청되면 가장 멀리 있는 페이지(예: B)를 교체합니다.
4. 페이지 결핍 (Page Fault)
정의
페이지 결핍은 실행 중인 프로그램이 접근하려는 페이지가 현재 물리 메모리에 존재하지 않을 때 발생하는 이벤트입니다. 이 경우, 운영체제는 요청한 페이지를 메모리에 로드해야 하며, 이 과정에서 일반적으로 디스크(I/O)가 포함됩니다.
페이지 결핍의 발생 과정
프로그램 실행:
- 프로그램이 메모리에 로드되고 실행되기 시작합니다.
가상 주소 접근:
- 프로그램이 특정 가상 주소를 참조하려고 할 때, CPU는 가상 주소를 페이지 테이블을 통해 물리 주소로 변환합니다.
페이지 존재 확인:
- 운영체제는 페이지 테이블에 해당 페이지가 존재하는지 확인합니다.
- 페이지 테이블의 상태 비트가 "존재"가 아니라면 페이지 결핍이 발생합니다.
페이지 결핍 처리:
- 페이지 결핍이 발생하면 운영체제는 해당 페이지를 메모리에 로드하기 위한 과정을 시작합니다.
페이지 결핍 처리 과정
페이지 결핍 신호 송출:
- CPU는 페이지 결핍 신호를 운영체제에 전달합니다. 이 신호는 일반적으로 인터럽트 또는 예외 처리에 의해 발생합니다.
현재 프로세스 중단:
- 운영체제는 현재 프로세스를 일시적으로 중단하고, 페이지 결핍 처리 루틴으로 전환됩니다.
디스크에서 페이지 로드:
- 운영체제는 필요한 페이지가 디스크(일반적으로 스왑 영역 또는 파일 시스템에서)에서 어떤 위치에 있는지를 확인합니다.
- 그런 다음 해당 페이지를 디스크에서 찾아 물리 메모리에 로드합니다.
페이지 교체:
- 물리 메모리에 공간이 부족할 경우, 전체 메모리에서 페이지 교체을 수행해야 합니다. 운영체제는 페이지 교체 알고리즘을 사용하여 제거할 페이지를 결정합니다(예: LRU, FIFO 등).
페이지 테이블 업데이트:
- 요청한 페이지가 물리 메모리에 로드되면, 운영체제는 페이지 테이블을 업데이트하여 해당 가상 페이지가 이제 물리 메모리에서 사용 가능하다고 표시합니다.
- 존재하지 않던 페이지의 번호와 대응하는 프레임 번호를 설정하고 상태 비트와 수정 비트를 업데이트합니다.
프로세스 재개:
- 페이지가 성공적으로 로드되고 페이지 테이블이 업데이트된 후, 운영체제는 일시 정지된 프로세스를 다시 시작합니다.
- 이때 CPU는 페이지 결핍이 발생한 가상 주소로 다시 접근하게 됩니다.
예시로 이해하기
가상 주소 0x0000A000
를 참조하지만 해당 페이지가 페이지 테이블에 존재하지 않는 상황을 가정해 보겠습니다.
- CPU는 해당 주소로 접근하려고 시도합니다.
- 페이지 테이블을 확인했을 때, 페이지 번호에 해당하는 프레임이 없음을 발견하고 페이지 결핍을 발생시킵니다.
- 운영체제는 현재 프로세스를 중단하고, 디스크에서 해당 페이지를 찾습니다 (예: 페이지 2).
- 페이지를 디스크에서 로드하고, 물리 메모리의 빈 공간에 올립니다.
- 페이지 테이블을 업데이트하여 페이지 2가 물리 메모리에 로드되었음을 기록합니다.
- 프로그램은 다시 이전 실행 상태로 돌아가고,
0x0000A000
에 대한 요청을 성공적으로 처리합니다.
메모리 보호
메모리 보호는 여러 프로세스가 동시에 실행될 때, 각 프로세스의 메모리 공간이 서로 독립적이도록 보장하는 기법입니다. 이를 통해 한 프로세스가 다른 프로세스의 메모리 영역에 접근하거나 수정하는 것을 방지할 수 있습니다.
주요 개념
가상 주소 공간:
- 각 프로세스는 자신의 독립적인 가상 주소 공간을 가집니다. 이는 프로세스가 사용하는 메모리 주소가 실제 물리 주소와 다르게 매핑됨을 의미합니다.
페이지 테이블:
- 프로세스마다 페이지 테이블이 존재하여, 운영체제는 이 테이블을 통해 각 프로세스의 가상 주소를 물리 주소와 매핑합니다. 페이지 테이블이 각 프로세스에 대해 독립적으로 유지되므로, 불법적인 메모리 접근이 방지됩니다.
상태 비트:
- 페이지 테이블의 상태 비트에는 페이지의 접근 권한 정보가 포함됩니다. 예를 들어, 읽기, 쓰기, 실행 권한 등을 설정할 수 있습니다. 이를 통해 프로세스가 어떤 페이지에 접근할 수 있는지를 결정합니다.
메모리 보호의 예시
- 프로세스 A가 자신의 메모리 공간에서
0x1000
의 주소를 참조할 때, 운영체제는 페이지 테이블을 조회하여 이 주소가 A가 접근할 수 있는 메모리인지 확인합니다. 만약 이 주소가 B의 공간에 속한다면, 페이지 결핍 예외가 발생하여 접근이 거부됩니다.
메모리 공유
메모리 공유는 다수의 프로세스가 동일한 메모리 영역을 공유할 수 있도록 허용하는 기법입니다. 이를 통해 데이터의 복사 없이 효율적으로 데이터를 교환할 수 있습니다.
주요 개념
공유 페이지:
- 특정 페이지를 여러 프로세스가 공유하도록 설정할 수 있습니다. 이를 통해 페이지를 복사하지 않고도 필요한 데이터에 접근할 수 있습니다. 예를 들어, 라이브러리나 공통 데이터를 여러 프로세스가 참조할 수 있습니다.
IPC (Inter-Process Communication):
- 메모리 공유는 IPC의 한 형태로, 여러 프로세스 간의 데이터 전송과 통신을 용이하게 합니다. 공유 메모리 기법을 통해 프로세스는 두 개의 메모리 공간을 عِه하다 καιذا로 접근할 수 있습니다.
메모리 공유의 예시
프로세스 A와 프로세스 B가 공통으로 사용할 데이터가 있다고 가정해 보겠습니다.
- 운영체제는 특정 페이지를 공유 가능하도록 설정합니다.
- 공유 페이지는 페이지 테이블에서 두 프로세스 모두 참조되도록 매핑됩니다.
- 프로세스 A가 페이지에 작성하면, 프로세스 B는 이를 즉시 읽을 수 있습니다. 두 프로세스가 서로의 메모리 공간을 공유하여 데이터를 교환할 수 있습니다.
6. 운영체제의 메모리 관리
운영체제의 메모리 관리는 메모리를 효율적으로 할당하고 관리하는 데 필요한 기법과 알고리즘을 포함합니다. 이는 시스템 성능을 유지하고 안정성을 확보하는 데 중요한 역할을 합니다. 주로 사용되는 메모리 관리 기법에는 다음이 포함됩니다:
1. 메모리 할당 기법
고정 분할 (Fixed Partitioning):
- 메모리를 미리 정해진 크기의 고정된 파티션으로 나누어 할당합니다. 각 파티션은 하나의 프로세스에만 할당될 수 있으며, 전체 메모리 사용량이 적어질 수 있습니다.
- 장점: 구현이 간단하고 관리가 용이합니다.
- 단점: 파티션 크기에 따라 내부 단편화가 발생할 수 있습니다.
가변 분할 (Variable Partitioning):
- 프로세스의 크기에 따라 메모리를 동적으로 할당합니다. 프로세스가 종료되면 해당 영역을 해제하고, 필요할 때마다 메모리를 재할당합니다.
- 장점: 메모리의 효율적 사용이 가능합니다.
- 단점: 외부 단편화가 발생할 수 있으며, 할당을 위한 추가 관리가 필요합니다.
페이징 (Paging):
- 가상 메모리를 페이지 단위로 나누어 프로세스의 가상 주소와 물리 주소를 매핑합니다. 페이지는 고정된 크기(예: 4KB)로 정의됩니다.
- 장점: 내부 단편화를 줄일 수 있습니다. 물리 메모리의 비연속적 할당이 가능합니다.
- 단점: 페이지 테이블을 적재하고 관리해야 하며, 페이지 결핍 발생 시 성능 저하가 있을 수 있습니다.
세그멘테이션 (Segmentation):
- 프로세스의 주소 공간을 의미 있는 논리적 단위(세그먼트)로 나누는 기법입니다. 세그먼트는 크기가 다를 수 있으며, 각 세그먼트는 코드, 데이터, 스택 등을 포함합니다.
- 장점: 프로그램의 구조를 보다 자연스럽게 반영합니다.
- 단점: 세그먼트의 크기가 다양하므로 외부 단편화가 발생할 수 있습니다.
2. 메모리 할당 정책
선입선출 (First Come, First Served, FCFS):
- 요청된 순서로 메모리를 할당합니다. 간단하지만 공정성이나 효율성을 보장하지 않습니다.
최소 잔여 시간 (Shortest Job First, SJF):
- 예상 실행 시간이 가장 짧은 프로세스에 메모리를 우선적으로 할당합니다. 수행 시간이 짧은 작업을 우선적으로 처리하여 전체 시스템 성능을 개선합니다.
우선순위 기반 할당 (Priority Allocation):
- 프로세스의 우선순위에 따라 메모리를 할당합니다. 시스템의 중요성이나 긴급성에 따라 다양한 우선순위가 설정됩니다.
페어-쉐어 / 공정 공유 (Fair Share):
- 모든 프로세스가 균등하게 메모리를 공유하도록 할당하여 다양한 프로세스들의 공정성을 제공합니다.
3. 스왑 (Swapping)
스왑은 물리 메모리를 관리하기 위한 한 방법으로, 특정 프로세스의 메모리를 디스크의 스왑 영역으로 이동시키는 것입니다. 이는 이 프로세스가 필요하지 않을 때 메모리를 해제하고, 다른 프로세스를 위해 메모리 공간을 확보합니다.
- 스와핑 절차:
- 스왑 공간이 부족할 경우, 운영체제는 특정 프로세스의 페이지들을 스왑 공간으로 이동시키고, 물리 메모리의 공간을 확보합니다.
- 스와핑된 프로세스는 나중에 필요한 경우 다시 메모리에 로드됩니다, 이때 페이지 결핍 처리가 발생할 수 있습니다.
'SW 사관학교 정글(Jungle) > 운영체제-PintOS' 카테고리의 다른 글
kaist-pintos 구현 중 aws중지 후 다시 켰는데 테스트 안 돌아갈 때 (0) | 2024.10.13 |
---|---|
[PintOS Project 3 - VIRTUAL MEMORY] Memory management 구현 중.. 간단한 예시로 흐름 파악하기(사용자가 arr[1024]를 요구했다면!) (1) | 2024.10.12 |
[PintOS Project 3 - VIRTUAL MEMORY] 가상 메모리 이론 공부2 운영체제가 관여하는 Virtual Memory (1) | 2024.10.09 |
[PintOS Project 3 - VIRTUAL MEMORY] 가상 메모리 이론 공부1 물리적인 메모리 관리(Memory Management) (2) | 2024.10.08 |
syscall-entry.S (1) | 2024.10.08 |