메모리 관리는 운영체제의 핵심 기능 중 하나로, 컴퓨터 시스템의 주기억장치(RAM)를 효율적으로 할당하고 관리하는 과정을 의미한다. 이는 다중 프로그래밍 환경에서 여러 프로세스가 동시에 실행될 때, 각 프로세스에 필요한 메모리를 안전하고 공정하게 배분하며, 제한된 물리 메모리 자원을 극대화하는 것을 목표로 한다. 메모리 관리는 시스템의 전반적인 성능과 안정성에 직접적인 영향을 미치는 중요한 요소이다.
주요 관리 기법으로는 페이징과 가상 메모리, 세그멘테이션 등이 있다. 페이징은 프로세스의 주소 공간을 고정 크기의 블록인 '페이지'로 나누고, 물리 메모리도 같은 크기의 '프레임'으로 나누어 매핑하는 방식이다. 가상 메모리는 페이징을 기반으로, 프로세스 전체가 물리 메모리에 상주하지 않아도 실행될 수 있도록 하는 기술이다. 이를 통해 실제 물리 메모리 용량보다 큰 프로그램을 실행할 수 있으며, 요구 페이징과 페이지 교체 알고리즘이 핵심 메커니즘으로 작동한다.
메모리 관리의 핵심 과제는 주소 변환, 메모리 보호, 메모리 공유를 효율적으로 구현하는 것이다. MMU(Memory Management Unit) 같은 하드웨어 지원을 통해 논리 주소를 물리 주소로 변환하고, 한 프로세스가 다른 프로세스의 메모리 영역을 침범하지 못하도록 보호한다. 동시에, 라이브러리 코드 같은 공통 데이터는 여러 프로세스가 안전하게 공유할 수 있도록 한다. 이러한 관리 기법들은 현대의 리눅스, 윈도우를 포함한 대부분의 운영체제에서 광범위하게 적용되고 있다.
메모리 관리는 운영체제가 물리 메모리를 효율적으로 할당하고 추적하며, 여러 프로세스 간의 메모리 공간을 분리하고 보호하는 기능을 말한다. 이는 컴퓨터 시스템의 안정성과 성능을 보장하는 핵심 요소이다. 기본 개념은 물리 메모리와 가상 메모리의 구분, 주소 공간과 그 변환, 그리고 메모리 보호와 공유의 메커니즘을 중심으로 구성된다.
물리 메모리 vs 가상 메모리
물리 메모리는 컴퓨터에 실제로 설치된 RAM(Random Access Memory) 하드웨어를 가리킨다. 각 바이트는 고유한 물리 주소를 가지며, CPU는 이 주소를 통해 직접 데이터를 읽거나 쓴다. 반면, 가상 메모리는 각 프로세스에 제공되는 논리적인 메모리 공간이다. 프로세스는 물리 메모리의 실제 배치와 무관하게, 자신만의 연속된 가상 주소 공간(예: 0번지부터 시작)을 사용하여 작업한다. 이 두 공간을 매핑하는 것은 운영체제와 MMU(Memory Management Unit)의 핵심 임무이다.
주소 공간과 주소 변환
각 프로세스는 독립적인 가상 주소 공간(논리 주소 공간)을 가진다. 프로세스가 메모리를 참조할 때 사용하는 주소는 이 가상 주소이다. MMU는 이 가상 주소를 실제 데이터가 위치한 물리 주소로 변환하는 작업을 수행한다. 이 변환 과정은 운영체제가 관리하는 페이지 테이블 등의 자료 구조를 통해 이루어진다. 주소 변환은 메모리 접근마다 발생하므로, 그 오버헤드를 최소화하기 위해 TLB(Translation Lookaside Buffer)라는 고속 캐시가 사용된다.
메모리 보호와 공유
메모리 관리의 또 다른 중요한 목표는 보호와 공유이다. 운영체제는 주소 변환 과정을 통해 한 프로세스가 다른 프로세스의 메모리 영역이나 운영체제 자신의 영역을 함부로 접근하지 못하도록 차단한다. 이는 일반적으로 페이지 테이블 항목에 설정된 읽기/쓰기/실행 권한 비트를 통해 구현된다[1]. 동시에, 여러 프로세스가 공통으로 사용하는 코드(예: 표준 C 라이브러리)나 데이터는 물리 메모리의 동일한 프레임에 매핑하여 메모리를 효율적으로 공유할 수 있다.
물리 메모리는 컴퓨터 시스템에 실제로 설치된 RAM과 같은 주기억장치를 가리킨다. 이는 CPU가 직접 접근하여 데이터를 읽고 쓸 수 있는 유한한 공간이다. 물리 메모리의 크기는 시스템 성능에 직접적인 영향을 미치며, 각 메모리 셀은 고유한 물리 주소를 가진다.
반면 가상 메모리는 운영체제가 제공하는 추상화 계층으로, 각 프로세스에 커다란 연속적인 주소 공간을 할당하는 메모리 관리 기법이다. 이 공간은 물리 메모리와 보조기억장치(예: HDD, SSD)를 결합하여 구현된다. 프로세스는 가상 주소를 사용하며, 이 주소는 MMU에 의해 실제 물리 주소로 변환된다.
두 메모리 유형의 주요 차이점은 다음과 같다.
구분 | 물리 메모리 | 가상 메모리 |
|---|---|---|
본질 | 하드웨어(실제 RAM 칩) | 소프트웨어(운영체제가 제공하는 추상화) |
크기 | 시스템에 설치된 RAM 용량으로 제한됨 | 프로세스당 사용 가능한 주소 공간이 매우 큼(예: 64비트 시스템에서는 2^64 바이트) |
주소 | 물리 주소(Physical Address) | 가상 주소(Virtual Address) 또는 논리 주소(Logical Address) |
관리 주체 | 하드웨어 수준에서 관리 | 운영체제의 메모리 관리자가 관리 |
가상 메모리의 핵심 목적은 물리 메모리의 한계를 극복하고, 메모리 보호, 메모리 공유, 프로그래밍의 편의성을 제공하는 것이다. 이를 통해 각 프로그램은 마치 시스템의 전체 물리 메모리를 독점하는 것처럼 동작할 수 있다.
프로세스가 사용하는 메모리 주소는 논리 주소(또는 가상 주소)이며, 이는 물리 메모리의 실제 위치인 물리 주소와 구분된다. 운영체제와 메모리 관리 장치(MMU)는 이 두 주소 공간 간의 변환을 담당하여 각 프로세스에게 독립적이고 연속적인 메모리 공간을 제공한다.
주소 변환의 핵심은 페이지 테이블이다. 페이지 테이블은 논리 주소 공간을 일정 크기로 나눈 페이지가 물리 메모리의 어떤 프레임에 매핑되어 있는지를 기록한다. 변환 과정은 다음과 같다.
1. 프로세스가 생성한 논리 주소는 페이지 번호와 페이지 내 오프셋으로 분리된다.
2. 페이지 테이블에서 해당 페이지 번호를 인덱스로 사용하여 물리 프레임 번호를 찾는다.
3. 찾은 물리 프레임 번호와 원래의 오프셋을 결합하여 최종 물리 주소를 생성한다.
이 변환은 메모리 관리 장치(MMU)에 의해 하드웨어 수준에서 투명하게 수행된다. 페이지 테이블은 주로 물리 메모리에 상주하므로, 매번 메모리 접근 시 추가로 페이지 테이블을 조회해야 하는 오버헤드가 발생할 수 있다. 이를 극복하기 위해 변환 색인 버퍼(TLB)라는 고속 캐시가 사용된다. TLB는 최근 사용된 페이지 번호와 프레임 번호의 매핑을 저장하여 변환 속도를 크게 향상시킨다[2].
프로세스는 서로 독립된 주소 공간에서 실행되며, 운영체제는 메모리 관리 장치(MMU)와 페이지 테이블을 통해 각 프로세스의 메모리 접근을 제한한다. 이를 통해 한 프로세스가 다른 프로세스의 메모리 영역을 함부로 읽거나 쓰는 것을 방지하여 시스템의 안정성과 보안을 보장한다. 일반적으로 각 페이지 테이블 항목(PTE)에는 읽기, 쓰기, 실행 권한과 같은 보호 비트가 설정되어 있다.
메모리 공유는 여러 프로세스가 동일한 물리 메모리 프레임을 공유하여 사용하는 기법이다. 이는 주로 시스템 라이브러리(공유 라이브러리)나 공통 데이터를 효율적으로 관리하기 위해 적용된다. 공유 메모리 영역은 각 프로세스의 가상 주소 공간에 매핑되지만, 동일한 물리 메모리 프레임을 가리킨다. 이를 통해 메모리 사용량을 줄이고 프로세스 간 통신(IPC) 속도를 크게 향상시킬 수 있다.
보호와 공유는 페이지 테이블 구조를 통해 함께 구현된다. 운영체제는 공유할 메모리 영역에 대해 모든 관련 프로세스의 페이지 테이블 항목이 동일한 물리 프레임 번호를 가리키도록 설정한다. 동시에 각 프로세스의 접근 권한(읽기 전용, 읽기/쓰기 등)을 개별적으로 제어할 수 있어, 필요한 경우 데이터의 무결성을 유지한다.
보호 메커니즘 | 설명 |
|---|---|
권한 비트 | 페이지 테이블 항목(PTE)에 설정된 읽기/쓰기/실행 권한으로, 무단 접근을 차단한다. |
사용자/커널 모드 | 특정 페이지를 커널 모드에서만 접근 가능하도록 설정하여 사용자 프로세스의 접근을 제한한다. |
주소 공간 분리 | 각 프로세스가 독립된 가상 주소 공간을 가지도록 하여, 다른 프로세스의 메모리를 인지하지 못하게 한다. |
공유 메커니즘 | 설명 |
|---|---|
공유 라이브러리 |
|
공유 메모리(IPC) | 프로세스 간 통신을 위해 명시적으로 생성된 메모리 영역을 공유한다. |
Copy-on-Write | 초기에는 페이지를 공유하다가, 어떤 프로세스가 쓰기를 시도할 때만 해당 페이지의 사본을 만든다[3]. |
페이징은 운영체제의 메모리 관리 기법 중 하나로, 프로세스의 논리적 주소 공간을 동일한 크기의 블록인 페이지로 나누고, 물리 메모리도 같은 크기의 프레임으로 나누어 페이지를 프레임에 할당하는 방식이다. 이 방법은 연속 메모리 할당의 단점인 외부 단편화 문제를 해결한다. 각 프로세스는 연속적인 물리 메모리 공간을 필요로 하지 않으며, 페이지가 비연속적인 프레임에 배치될 수 있다. 운영체제는 페이지 테이블을 사용하여 각 프로세스의 논리적 페이지 번호를 물리적 프레임 번호로 매핑한다.
페이징 시스템의 핵심 자료 구조는 페이지 테이블이다. 각 프로세스는 자신의 페이지 테이블을 가지며, 이 테이블은 CPU가 생성하는 모든 논리적 주소에 대해 물리적 주소로의 변환 정보를 담고 있다. 주소 변환은 논리적 주소를 페이지 번호와 페이지 오프셋으로 나누는 과정을 포함한다. 페이지 번호는 페이지 테이블의 인덱스로 사용되어 해당 페이지의 기준 물리 주소(프레임 번호)를 찾고, 여기에 오프셋을 더해 최종 물리 주소를 얻는다. 이 변환 과정은 메모리 관리 장치가 담당하며, 성능 향상을 위해 자주 사용되는 변환 정보는 변환 색인 버퍼라는 고속 캐시에 저장된다.
페이징의 주요 장점과 단점은 다음과 같다.
장점 | 단점 |
|---|---|
외부 단편화가 발생하지 않음 | 내부 단편화가 발생할 수 있음 |
메모리 할당과 해제가 간단하고 효율적 | 주소 변환을 위한 페이지 테이블로 인한 오버헤드 발생 |
비연속적 할당으로 메모리 활용도 향상 | 각 메모리 접근마다 최소 두 번의 물리 메모리 접근 필요(페이지 테이블 접근 + 실제 데이터 접근) |
가상 메모리 구현의 기초가 됨 | 대용량 페이지 테이블을 저장하기 위한 추가 메모리 공간 필요 |
페이징은 현대 운영체제에서 가상 메모리를 구현하는 근간이 된다. 이를 통해 프로세스 전체를 물리 메모리에 상주시킬 필요 없이, 당장 실행에 필요한 페이지만 메모리에 적재하는 요구 페이징이 가능해진다. 또한, 공유 라이브러리나 코드를 여러 프로세스가 같은 물리 프레임을 가리키는 페이지 테이블 항목을 통해 공유할 수 있어 메모리 효율성을 높인다.
페이징은 운영체제가 물리 메모리를 고정 크기의 블록인 프레임으로 나누고, 프로세스의 가상 메모리 주소 공간을 같은 크기의 블록인 페이지로 나누어 관리하는 기법이다. 각 프로세스는 연속적인 가상 주소 공간을 할당받지만, 이 공간의 페이지들은 물리 메모리 내의 프레임에 연속적으로 할당될 필요가 없다. 이로 인해 프로세스의 물리 메모리 배치가 연속적이지 않아도 되므로, 외부 단편화 문제를 효과적으로 해결한다.
페이징 시스템의 핵심 구조는 페이지 테이블이다. 페이지 테이블은 각 프로세스마다 존재하며, 가상 페이지 번호를 해당 페이지가 적재된 물리 프레임 번호로 매핑하는 역할을 한다. CPU가 생성한 가상 주소는 페이지 번호와 페이지 내 오프셋으로 나뉘며, 메모리 관리 장치는 페이지 테이블을 조회하여 페이지 번호에 대응하는 프레임 번호를 찾아낸다. 이후 프레임 번호와 오프셋을 결합하여 실제 물리 주소를 만들어낸다.
페이징의 주요 구성 요소와 데이터 구조는 다음과 같다.
구성 요소 | 설명 |
|---|---|
프로세스의 가상 주소 공간을 일정한 크기로 나눈 논리적 단위이다. | |
물리 메모리를 페이지와 동일한 크기로 나눈 물리적 단위이다. | |
각 프로세스마다 존재하며, 페이지 번호와 프레임 번호의 매핑 정보를 저장한다. | |
현재 실행 중인 프로세스의 페이지 테이블 시작 주소를 가리킨다. |
이 구조 하에서 운영체제는 메모리를 효율적으로 관리할 수 있다. 예를 들어, 프로세스 실행에 필요한 페이지들만 물리 메모리에 적재하고, 그렇지 않은 페이지는 보조기억장치에 남겨둘 수 있다. 또한, 여러 프로세스가 동일한 코드 페이지를 공유하는 등의 메모리 공유도 페이지 단위로 구현이 가능해진다.
페이지 테이블은 가상 주소 공간과 물리 메모리 간의 매핑 정보를 저장하는 핵심적인 자료 구조이다. 각 프로세스는 자신만의 페이지 테이블을 가지며, 운영체제가 이를 관리한다. 페이지 테이블의 각 항목(PTE, Page Table Entry)은 해당 가상 페이지가 매핑된 물리 프레임의 주소와 함께, 페이지의 접근 권한(읽기/쓰기/실행), 존재 비트(해당 페이지가 물리 메모리에 적재되었는지 여부), 참조 비트, 수정 비트 등의 제어 정보를 포함한다.
주소 변환 과정에서 CPU가 생성한 가상 주소는 페이지 번호와 페이지 내 오프셋으로 나뉜다. 페이지 번호는 페이지 테이블의 인덱스로 사용되어 해당 PTE를 찾고, PTE에 저장된 물리 프레임 번호와 원래의 오프셋을 결합하여 최종 물리 주소가 만들어진다. 그러나 이 변환은 메모리 접근 자체보다 추가적인 메모리 참조(페이지 테이블 조회)를 필요로 하므로 성능 저하의 주요 원인이 된다.
이 성능 문제를 완화하기 위해 TLB(Translation Lookaside Buffer)가 사용된다. TLB는 페이지 테이블의 일부 항목을 캐싱하는 고속의 하드웨어 캐시이다. 주소 변환 시 CPU는 먼저 TLB를 검색하고(TLB 히트), 해당 가상 페이지의 변환 정보가 TLB에 존재하면 물리 메모리에 접근하는 페이지 테이블 조회를 생략할 수 있다. TLB에 정보가 없으면(TLB 미스) 일반적인 페이지 테이블 조회를 수행하고, 그 결과를 TLB에 적재한다. TLB의 히트율은 시스템의 전체적인 메모리 접근 성능에 지대한 영향을 미친다.
용어 | 설명 |
|---|---|
가상 페이지 번호를 물리 프레임 번호로 변환하는 매핑 테이블. 각 프로세스마다 별도로 존재한다. | |
페이지 테이블 항목. 물리 프레임 번호와 접근 제어 비트들을 포함한다. | |
최근 사용된 가상-물리 주소 변환 쌍을 저장하는 고속 하드웨어 캐시. | |
요청된 가상 페이지의 변환 정보가 TLB에 존재하는 상태. 빠른 변환이 가능하다. | |
요청된 가상 페이지의 변환 정보가 TLB에 없는 상태. 전체 페이지 테이블 조회가 필요하다. |
TLB는 일반적으로 완전 연관 또는 집합 연관 매핑 방식을 사용하며, 컨텍스트 스위칭이 발생하면 새로운 프로세스의 주소 공간을 반영하기 위해 TLB의 내용을 무효화하거나(TLB 플러시), 각 TLB 항목에 ASID(Address Space Identifier)를 태그로 붙여 구분한다.
페이징은 물리 메모리를 고정 크기의 블록인 페이지로, 가상 메모리 공간을 동일한 크기의 가상 페이지로 나누어 관리하는 방식이다. 이 방식의 주요 장점은 메모리 단편화 문제를 효과적으로 해결한다는 점이다. 외부 단편화가 거의 발생하지 않아, 물리 메모리에 흩어져 있는 여러 개의 작은 여유 공간(페이지 프레임)을 효율적으로 활용할 수 있다. 또한, 각 프로세스의 주소 공간이 연속적일 필요가 없어 메모리 할당과 관리가 단순해진다. 이는 메모리 관리 장치의 설계를 용이하게 하고, 요구 페이징과 같은 고급 기법을 구현하는 기반을 제공한다.
그러나 페이징은 몇 가지 명확한 단점을 동반한다. 가장 큰 문제는 내부 단편화다. 프로세스가 필요로 하는 메모리 크기가 페이지 크기의 배수가 아닐 경우, 마지막 페이지의 일부 공간이 낭비된다. 페이지 크기가 클수록 내부 단편화의 평균 크기도 증가하는 경향이 있다. 또한, 주소 변환을 위한 페이지 테이블은 상당한 메모리 공간을 차지한다. 특히 64비트 시스템처럼 주소 공간이 매우 클 경우, 페이지 테이블의 크기가 부담이 될 수 있다. 이 문제를 완화하기 위해 다단계 페이지 테이블이나 역페이지 테이블 같은 기법이 사용된다.
성능 측면에서도 과제가 존재한다. 모든 메모리 접근마다 페이지 테이블을 참조해야 하므로, 이는 추가적인 메모리 접근을 의미한다. 이 오버헤드를 줄이기 위해 변환 색인 버퍼라는 고속 캐시 하드웨어가 필수적이다. TLB 미스가 발생하면 페이지 테이블 접근을 포함한 여러 번의 메모리 참조가 필요해 성능이 저하될 수 있다. 따라서 페이징 시스템의 효율성은 TLB의 히트율과 페이지 크기, 페이지 테이블 구조의 설계에 크게 의존한다.
장점 | 설명 |
|---|---|
단편화 감소 | 외부 단편화가 거의 발생하지 않음. 내부 단편화는 존재할 수 있음. |
메모리 관리 용이 | 비연속 할당으로 메모리 공간 활용도가 높고, 할당/해제가 간단함. |
가상 메모리 지원 | 요구 페이징, 페이지 공유, 쓰기 시 복사 등 고급 기능 구현의 기반이 됨. |
보호와 공유 | 페이지 단위로 읽기/쓰기/실행 권한 설정과 메모리 공유가 가능함. |
단점 | 설명 |
|---|---|
내부 단편화 | 프로세스 크기가 페이지 크기의 배수가 아니면 마지막 페이지 공간이 낭비됨. |
주소 변환 오버헤드 | 매 접근마다 페이지 테이블 조회가 필요하며, TLB 미스 시 성능 저하가 큼. |
페이지 테이블 공간 | 페이지 테이블 자체가 상당한 물리 메모리를 차지할 수 있음. |
설계 복잡성 | 다단계 페이지 테이블, TLB 관리, 페이지 교체 알고리즘 등 구현이 복잡함. |
가상 메모리는 물리 메모리의 크기 제한을 극복하고, 각 프로세스에게 독립적이고 연속적인 메모리 공간을 제공하기 위한 핵심적인 운영체제 기술이다. 이 기법은 프로그램이 사용하는 논리 주소(가상 주소)와 실제 데이터가 저장되는 물리 주소를 분리한다. 사용자 프로그램은 매우 큰 주소 공간(예: 32비트 시스템에서는 4GB)을 마치 자신만의 물리 메모리인 것처럼 사용할 수 있지만, 실제로는 필요한 부분만 물리 메모리에 적재되고 나머지는 보조 기억장치(주로 하드 디스크 드라이브의 스왑 영역)에 존재한다. 이를 통해 물리 메모리보다 큰 프로그램의 실행을 가능하게 하고, 메모리 공간의 효율적인 활용 및 프로세스 간 격리를 보장한다.
가상 메모리의 핵심 구현 방식은 페이징이다. 운영체제와 메모리 관리 장치(MMU)는 프로그램의 가상 주소 공간을 고정 크기의 블록인 페이지로 나누고, 물리 메모리 역시 동일한 크기의 프레임으로 나눈다. 프로그램 실행 중 특정 페이지에 접근하려 할 때, 해당 페이지가 물리 메모리에 존재하지 않으면 페이지 폴트(page fault)라는 예외가 발생한다. 이 예외를 처리하는 운영체제는 필요한 페이지를 디스크에서 물리 메모리로 불러온 후, 프로그램의 실행을 재개한다. 이처럼 페이지가 실제로 필요할 때 적재하는 방식을 요구 페이징(Demand Paging)이라고 한다.
요구 페이징 시스템에서 물리 메모리가 가득 차면, 새로운 페이지를 적재하기 위해 기존 페이지 중 하나를 선택해 디스크로 내보내야(swap out) 한다. 이때 어떤 페이지를 교체할지 결정하는 정책을 페이지 교체 알고리즘이라고 한다. 대표적인 알고리즘은 다음과 같다.
알고리즘 | 설명 | 특징 |
|---|---|---|
최적 페이지 교체(OPT) | 앞으로 가장 오랫동안 사용되지 않을 페이지를 교체 | 이상적인 알고리즘이지만 구현 불가능, 성능 비교 기준으로 사용 |
최근 최소 사용(LRU) | 가장 오랫동안 사용되지 않은 페이지를 교체 | OPT에 근접한 좋은 성능, 구현 오버헤드가 큼 |
선입선출(FIFO) | 가장 먼저 적재된 페이지를 교체 | 구현이 간단하지만 성능이 좋지 않을 수 있음 |
클럭 알고리즘(Second-Chance) | 참조 비트를 확인하며 교체 대상 페이지를 순환 탐색 | LRU의 근사 알고리즘, 합리적인 오버헤드와 성능 |
가상 메모리는 시스템의 성능과 안정성에 중요한 영향을 미친다. 페이지 폴트가 빈번하게 발생하면 디스크 입출력이 증가하여 전체 시스템 성능이 급격히 저하되는 쓰레싱(Thrashing) 현상이 발생할 수 있다. 이를 방지하기 위해 운영체제는 워킹셋 모델 등을 통해 각 프로세스에 적절한 수의 페이지 프레임을 할당하거나, 페이지 교체 알고리즘을 최적화한다.
가상 메모리는 운영체제가 제공하는 추상화 계층으로, 프로세스에게 매우 크고 연속적으로 보이는 주소 공간을 할당하는 기술이다. 이 공간은 가상 주소 공간이라고 불리며, 실제 물리 메모리의 크기와 무관하게 각 프로세스마다 독립적으로 할당된다. 핵심 아이디어는 프로세스가 사용하는 주소(논리 주소)와 실제 데이터가 저장되는 물리 메모리의 주소(물리 주소)를 분리하는 것이다. 이 분리는 메모리 관리 장치(MMU)를 통한 하드웨어 지원과 운영체제의 소프트웨어 정책이 결합되어 구현된다.
가상 메모리의 도입은 몇 가지 중요한 필요성에 의해 촉진되었다. 첫째, 다중 프로그래밍 환경에서 여러 프로세스가 동시에 메모리에 상주할 때, 프로세스의 크기가 실제 물리 메모리보다 클 수 있는 문제를 해결한다. 둘째, 물리 메모리의 단편화 문제를 완화한다. 가상 메모리 하에서는 프로세스가 연속적인 물리 공간을 필요로 하지 않으며, 페이징 기법을 통해 비연속적인 물리 프레임에 배치될 수 있다. 셋째, 메모리 보호와 공유를 용이하게 한다. 각 프로세스는 고유한 가상 주소 공간을 가지므로, 다른 프로세스의 메모리를 의도치 않게 접근하는 것을 방지할 수 있다. 동시에, 운영체제는 특정 페이지(예: 공유 라이브러리 코드)를 여러 프로세스의 가상 공간에 매핑하여 메모리 효율성을 높일 수 있다.
이 기술의 가장 큰 장점은 사용자 프로그램이 물리 메모리의 제약에서 자유로워진다는 점이다. 프로그래머는 매우 큰 주소 공간을 가정하고 프로그램을 작성할 수 있으며, 운영체제와 하드웨어가 필요한 부분만 물리 메모리에 적재하고 나머지는 보조기억장치(일반적으로 하드 디스크 드라이브의 스왑 영역)에 보관한다. 이로 인해 실제 물리 메모리 용량보다 더 큰 여러 프로그램을 동시에 실행하는 것이 가능해진다. 그러나 이는 시스템 성능에 trade-off를 초래한다. 필요한 데이터가 보조기억장치에 있을 경우, 이를 물리 메모리로 불러오는 페이지 폴트 처리로 인한 오버헤드가 발생하기 때문이다.
요구 페이징은 가상 메모리 시스템이 실제로 필요할 때만 물리 메모리에 페이지를 적재하는 방식이다. 프로그램 실행 시작 시 모든 페이지를 메모리에 올리지 않고, 초기에는 필요한 최소한의 페이지만 로드한다. 이후 프로그램이 접근하는 페이지가 메모리에 없는 경우, 즉 페이지 폴트가 발생하면 그때 해당 페이지를 보조기억장치(예: 하드 디스크나 SSD)에서 물리 메모리로 읽어온다. 이 방식은 메모리 공간을 효율적으로 사용하고, 프로그램 시작 시간을 단축시키며, 실제 물리 메모리 크기보다 더 큰 프로그램을 실행할 수 있게 한다.
요구 페이징의 동작 과정은 다음과 같다. 프로세스가 특정 가상 주소를 참조하면, MMU는 해당 주소가 속한 페이지가 물리 메모리에 존재하는지 확인한다. 페이지가 존재하면(페이지 히트) 정상적으로 접근한다. 존재하지 않으면(페이지 폴트) 운영체제의 페이지 폴트 핸들러가 호출된다. 핸들러는 요청된 페이지를 보조기억장치에서 찾아 빈 물리 프레임에 적재하고, 페이지 테이블을 갱신한다. 이후 중단되었던 프로세스의 명령어가 재실행되어 메모리 접근을 성공적으로 완료한다.
요구 페이징의 성능은 페이지 폴트 발생 빈도에 크게 의존한다. 페이지 폴트는 보조기억장치 접근이 수반되므로 처리 시간이 매우 길다. 따라서 페이지 참조 지역성을 활용하여 폴트율을 낮추는 것이 중요하다. 또한, 물리 메모리가 가득 찬 상태에서 페이지 폴트가 발생하면, 새로운 페이지를 올리기 위해 기존 페이지 중 하나를 선택하여 보조기억장치로 내보내는(페이지 아웃) 작업이 추가로 필요하다. 이때 어떤 페이지를 교체할지 결정하는 페이지 교체 알고리즘의 효율성이 전체 시스템 성능에 큰 영향을 미친다.
페이지 교체 알고리즘은 가상 메모리 시스템에서 물리 메모리가 가득 찼을 때, 새로운 페이지를 올리기 위해 기존의 어떤 페이지를 스왑 영역으로 내보낼지 결정하는 규칙이다. 이 알고리즘의 목표는 페이지 폴트 발생률을 최소화하여 시스템 성능을 높이는 것이다. 이상적인 알고리즘은 앞으로 가장 오랫동안 사용되지 않을 페이지를 교체하는 것이지만, 미래의 접근 패턴을 알 수 없기 때문에 실제로는 근사적인 방법들을 사용한다.
대표적인 페이지 교체 알고리즘은 다음과 같다.
알고리즘 | 설명 | 특징 |
|---|---|---|
FIFO(First-In First-Out) | 가장 먼저 적재된 페이지를 교체한다. | |
최적 교체(OPT, Optimal) | 앞으로 가장 오랫동안 사용되지 않을 페이지를 교체한다. | 미래를 알 수 있어 실현 불가능하지만, 다른 알고리즘의 성능 비교 기준으로 사용된다. |
LRU(Least Recently Used) | 가장 오랫동안 사용되지 않은 페이지를 교체한다. | 접근된 지 가장 오래된 페이지를 제거한다. 과거의 접근 이력을 기반으로 하여 OPT에 근접한 좋은 성능을 보인다. |
LFU(Least Frequently Used) | 가장 적게 사용된 페이지를 교체한다. | 접근 빈도가 가장 낮은 페이지를 제거한다. 초기에 많이 사용된 후 더 이상 사용되지 않는 페이지가 메모리를 차지하는 문제가 발생할 수 있다. |
클럭 알고리즘(Clock, Second-Chance) | 참조 비트(Reference Bit)를 확인하며, 참조 비트가 0인 페이지를 교체한다. | 원형 큐 형태로 페이지를 관리하며, 참조 비트가 1인 페이지는 기회를 한 번 더 주고 비트를 0으로 설정한다. LRU의 근사 알고리즘으로 널리 사용된다. |
알고리즘 선택은 시스템의 워크로드 특성과 구현 복잡도 사이의 절충을 고려해야 한다. LRU는 성능이 우수하지만, 정확한 구현을 위해서는 각 페이지 접근 시간을 기록하거나 리스트를 관리하는 오버헤드가 존재한다. 따라서 실제 시스템에서는 하드웨어 지원을 받는 클럭 알고리즘과 같은 근사적 방법이 더 많이 채택된다. 또한, 변형 클럭 알고리즘은 참조 비트와 더불어 수정 비트(Dirty Bit)를 함께 고려하여, 수정되지 않은 페이지를 우선적으로 교체함으로써 쓰기 동작이 필요한 디스크 I/O 오버헤드를 줄이는 최적화를 제공한다.
세그멘테이션은 프로세스의 논리적 주소 공간을 의미 있는 단위인 세그먼트(Segment)로 나누어 관리하는 메모리 관리 기법이다. 각 세그먼트는 함수, 데이터 구조, 힙, 스택 등과 같이 프로그램의 논리적 구성 요소에 대응된다. 이 방식은 페이징이 물리 메모리를 고정된 크기의 페이지로 나누는 것과 달리, 가변 크기의 논리적 단위를 기반으로 한다.
세그멘테이션 시스템에서는 논리적 주소가 <세그먼트 번호, 오프셋>의 쌍으로 구성된다. 운영체제는 각 프로세스별로 세그먼트 테이블(Segment Table)을 유지하며, 이 테이블은 각 세그먼트의 물리 메모리 내 시작 주소(베이스, Base)와 길이(한계, Limit)를 저장한다. MMU는 주소 변환 시 세그먼트 번호로 테이블을 참조하여 베이스 주소를 얻고, 오프셋을 더해 물리 주소를 계산한다. 동시에 오프셋이 세그먼트의 한계 길이를 초과하지 않는지 검사하여 메모리 보호를 제공한다.
특성 | 페이징 (Paging) | 세그멘테이션 (Segmentation) |
|---|---|---|
단위 | 고정 크기(페이지) | 가변 크기(세그먼트) |
분할 기준 | 물리적(시스템 관점) | 논리적(프로그램 관점) |
내부 단편화 | 발생 가능 | 발생하지 않음 |
외부 단편화 | 발생하지 않음 | 발생 가능 |
공유 및 보호 | 페이지 단위 | 의미 있는 세그먼트 단위 |
주소 변환 구조 | 페이지 테이블 | 세그먼트 테이블 |
세그멘테이션의 주요 장점은 논리적 구조를 반영하기 때문에 메모리 보호와 공유를 보다 효율적으로 구현할 수 있다는 점이다. 예를 들어, 코드 세그먼트는 읽기 전용으로, 데이터 세그먼트는 읽기-쓰기로 설정하는 것이 용이하다. 반면, 가변 크기 할당으로 인해 외부 단편화가 발생할 수 있으며, 이는 메모리 압축과 같은 추가적인 관리 오버헤드를 유발한다. 이러한 단점으로 인해 현대 범용 운영체제는 순수 세그멘테이션보다는 페이징을 주로 사용하거나, 두 방식을 결합한 세그먼트-페이징 혼용 기법을 적용하기도 한다.
세그멘테이션은 프로그램의 논리적 구조에 따라 메모리를 관리하는 방식이다. 이 방식에서는 프로그램의 주소 공간을 코드, 데이터, 스택, 힙 등과 같은 논리적 단위인 세그먼트로 나눈다. 각 세그먼트는 연속된 물리 메모리 공간에 할당되며, 독자적인 크기를 가진다. 운영체제는 세그먼트 테이블을 유지하여 각 세그먼트의 물리 메모리 시작 주소(베이스 레지스터)와 길이(한계 레지스터)를 관리한다.
프로세스가 논리 주소를 참조할 때, 주소는 일반적으로 세그먼트 번호와 세그먼트 내 오프셋으로 구성된다. 메모리 관리 장치(MMU)는 세그먼트 번호를 인덱스로 사용해 세그먼트 테이블에서 해당 세그먼트의 베이스 주소를 찾는다. 그 후 오프셋이 세그먼트 길이보다 작은지 확인하여 접근이 유효한지 검사한다. 유효하면 베이스 주소에 오프셋을 더해 최종 물리 주소를 계산한다. 이 과정을 통해 메모리 보호가 구현된다. 각 세그먼트는 독립적인 접근 권한(읽기, 쓰기, 실행)을 가질 수 있어, 잘못된 접근을 방지한다.
세그멘테이션의 주요 장점은 프로그래머의 관점과 일치하는 논리적 메모리 보호와 공유가 용이하다는 점이다. 예를 들어, 동일한 코드 세그먼트를 여러 프로세스가 공유하여 메모리 사용 효율을 높일 수 있다. 그러나 단점으로는 외부 단편화가 발생하기 쉽다는 문제가 있다. 각 세그먼트의 크기가 가변적이므로 메모리에 빈 공간이 산발적으로 생기고, 이로 인해 총 여유 공간은 충분함에도 새로운 세그먼트를 할당할 수 없는 상황이 발생한다. 이 문제를 완화하기 위해 메모리 압축 기법이 사용되지만, 이는 추가적인 오버헤드를 유발한다.
페이징과 세그멘테이션은 모두 가상 메모리를 구현하는 주요 기법이지만, 메모리를 나누는 단위와 관리 방식에서 근본적인 차이를 보인다. 페이징은 메모리를 고정된 크기의 블록인 페이지로 나누고, 프로세스의 주소 공간도 동일한 크기의 페이지로 분할하여 매핑한다. 반면, 세그멘테이션은 프로세스의 논리적 구조(예: 코드, 데이터, 스택 등)에 따라 가변 길이의 단위인 세그먼트로 나눈다. 이는 프로그래머의 관점에서 더 자연스러운 메모리 뷰를 제공하지만, 외부 단편화를 유발할 수 있다.
두 방식의 핵심적인 차이는 다음 표와 같이 정리할 수 있다.
비교 항목 | 페이징 (Paging) | 세그멘테이션 (Segmentation) |
|---|---|---|
메모리 분할 단위 | 고정 크기(페이지) | 가변 크기(세그먼트) |
단편화 | 내부 단편화 발생 가능 | 외부 단편화 발생 가능 |
사용자 관점 | 단일 선형 주소 공간(논리적 구조 숨김) | 다중 주소 공간(논리적 구조 반영) |
보호 및 공유 | 페이지 단위로 가능 | 세그먼트 단위로 더 용이함 |
주소 변환 | 페이지 번호 + 페이지 오프셋 | 세그먼트 번호 + 세그먼트 오프셋 |
관리 테이블 | 페이지 테이블 | 세그먼트 테이블 |
성능과 관리 측면에서 페이징은 일반적으로 더 효율적이다. 페이지의 고정 크기로 인해 메모리 할당과 해제가 단순하며, 스왑 공간 관리도 쉽다. 또한, 외부 단편화가 발생하지 않아 메모리 압축이 필요하지 않다. 단점으로는 프로그램의 논리적 구조를 무시하기 때문에 코드와 데이터의 공유나 보호 정책을 세밀하게 적용하기 어려울 수 있으며, 페이지 내의 남는 공간으로 인한 내부 단편화가 발생할 수 있다.
세그멘테이션은 논리적 단위로 메모리를 관리하여 의미 있는 보호(예: 코드 세그먼트는 읽기/실행만 허용)와 공유를 구현하기 쉽다는 장점이 있다. 그러나 가변 길이 세그먼트의 할당과 해제로 인해 외부 단편화가 심하게 발생할 수 있으며, 이는 주기적인 압축 작업을 필요로 하여 시스템 오버헤드를 증가시킨다. 현대 대부분의 범용 운영체제는 순수 세그멘테이션보다는 페이징을 주된 기법으로 사용하거나, 두 방식을 결합한 세그먼트-페이징 혼용 방식을 채택한다[6].
메모리 관리 장치(MMU)는 중앙 처리 장치(CPU)와 주 메모리 사이에 위치하는 하드웨어 구성 요소이다. MMU의 핵심 기능은 가상 주소를 물리 주소로 변환하는 것이다. 이 변환 과정은 운영체제가 설정한 페이지 테이블을 참조하여 수행된다. MMU는 모든 메모리 접근 요청을 가로채어 주소 변환을 적용하고, 변환된 물리 주소를 메모리 버스로 전달한다. 또한, MMU는 페이지 테이블 항목에 설정된 접근 권한(읽기, 쓰기, 실행)을 검사하여 잘못된 접근을 차단하는 메모리 보호 기능도 담당한다.
주소 변환 과정에서 페이지 테이블을 메모리에서 매번 조회하는 것은 성능에 큰 부담을 준다. 이를 해결하기 위해 MMU 내부 또는 근처에 변환 색인 버퍼(TLB)라는 특수한 고속 캐시가 존재한다. TLB는 최근에 사용된 가상 주소와 그에 대응하는 물리 주소의 매핑 정보를 저장한다. CPU가 가상 주소를 발생시키면 MMU는 먼저 TLB에서 해당 매핑을 찾는다(TLB 히트). 히트할 경우 물리 주소를 즉시 얻을 수 있어 변환이 매우 빠르게 완료된다. TLB에서 매핑을 찾지 못하면(TLB 미스), MMU는 메모리에 있는 페이지 테이블을 순회하여 물리 주소를 찾아내고, 그 결과를 TLB에 새로 저장한다.
MMU와 TLB의 동작은 운영체제와 긴밀하게 협력한다. 운영체제는 문맥 교환 시 새로운 프로세스의 페이지 테이블 기준 주소를 MMU의 특수 레지스터에 로드한다. 또한, TLB는 주소 공간이 변경되면 그 내용이 무효화되어야 한다. 일부 아키텍처에서는 TLB 항목을 소프트웨어가 명시적으로 관리해야 하며, 다른 아키텍처에서는 MMU가 자동으로 TLB를 관리하기도 한다. MMU가 탐지한 페이지 폴트나 보호 위반 같은 예외는 운영체제에 통보되어 처리된다.
하드웨어 구성 요소 | 주요 기능 | 성능 영향 |
|---|---|---|
메모리 관리 장치(MMU) | 가상-물리 주소 변환, 접근 권한 검사 | 주소 변환의 오버헤드 발생 |
변환 색인 버퍼(TLB) | 자주 사용하는 주소 변환 정보 캐싱 | TLB 히트율이 메모리 접근 성능을 결정 |
이러한 하드웨어 지원은 페이징과 가상 메모리 시스템이 실용적인 성능으로 동작할 수 있는 기반을 제공한다.
MMU는 CPU와 주 메모리 사이에 위치하여 가상 주소를 물리 주소로 변환하는 하드웨어 장치이다. 이 변환 과정은 운영체제가 설정한 페이지 테이블을 참조하여 수행된다. MMU의 핵심 기능은 모든 메모리 접근에 대해 변환을 투명하게 처리함으로써, 각 프로세스가 독립된 가상 주소 공간을 가질 수 있도록 보장하는 것이다. 이를 통해 메모리 보호와 메모리 공유가 가능해지며, 프로세스 간 간섭을 방지한다.
MMU의 주요 구성 요소와 동작은 다음과 같다.
구성 요소 / 개념 | 설명 |
|---|---|
주소 변환 장치 | |
페이지 테이블 베이스 레지스터(PTBR) | 현재 실행 중인 프로세스의 페이지 테이블 시작 주소를 가리킨다. 문맥 교환 시 운영체제가 이 값을 갱신한다. |
TLB(변환 색인 버퍼) | 자주 사용되는 가상-물리 주소 변환 쌍을 저장하는 고속 캐시이다. MMU는 먼저 TLB를 검사하여 변환 속도를 높인다. |
보호 비트 검사 | 페이지 테이블 항목에 저장된 읽기/쓰기/실행 권한 비트를 검사하여 허용되지 않은 접근을 차단한다. |
MMU는 페이지 폴트가 발생하면 CPU에 트랩을 발생시켜 운영체제의 페이지 폴트 핸들러가 개입하도록 한다. 또한, 캐시 메모리 시스템과 밀접하게 연동되어 동작한다. CPU가 내보내는 주소는 가상 주소이므로, 캐시는 이 가상 주소를 태그로 사용하거나(VIVT), MMU를 통해 변환된 물리 주소를 태그로 사용하거나(PIPT), 혼합 방식(VIPT)을 사용한다. MMU의 설계는 메모리 관리의 성능과 효율성에 직접적인 영향을 미치는 핵심 요소이다.
주소 변환 캐시(TLB, Translation Lookaside Buffer)는 가상 메모리 시스템에서 페이지 테이블 접근으로 인한 성능 저하를 완화하기 위한 하드웨어 캐시 장치이다. CPU 내부나 MMU 근처에 위치하며, 최근에 사용된 가상 주소와 물리 주소의 매핑 정보를 저장한다. TLB는 페이지 테이블에 대한 빠른 조회 캐시 역할을 하여, 모든 메모리 접근 시 물리 메모리에 있는 전체 페이지 테이블을 참조해야 하는 부담을 줄인다.
TLB의 동작은 다음과 같다. CPU가 가상 주소를 생성하면, 먼저 TLB를 검색한다. 해당 가상 페이지 번호(VPN)에 대한 변환 정보가 TLB에 존재하면 이를 TLB 히트(TLB hit)라고 하며, 저장된 물리 프레임 번호(PFN)를 즉시 사용한다. 정보가 TLB에 없으면 TLB 미스(TLB miss)가 발생하며, 이때는 메인 메모리에 있는 페이지 테이블을 검색하여 매핑 정보를 찾아야 한다. 찾은 정보는 이후 참조를 위해 TLB에 로드된다.
TLB의 성능은 히트율(hit rate)에 크게 의존한다. 높은 히트율을 유지하기 위해 다양한 설계 기법이 사용된다. TLB는 일반적으로 완전 연관 또는 집합 연관 매핑 방식을 사용하며, 교체 정책으로는 LRU(Least Recently Used)나 무작위 교체 알고리즘이 적용된다. 또한, ASID(Address Space Identifier)나 태그를 사용하여 서로 다른 프로세스의 주소 공간 변환 항목을 구분하고, TLB 플러시를 최소화한다.
TLB는 현대 컴퓨터 아키텍처에서 필수적인 구성 요소이다. 멀티태스킹 환경에서 문맥 교환(context switch)이 발생하면, 새 프로세스의 주소 공간에 대한 변환 정보가 필요하므로 TLB의 일부 또는 전체를 무효화해야 할 수 있다. 이 오버헤드를 줄이기 위해 ASID를 활용하는 등의 최적화가 이루어진다.
페이지 프리페칭은 프로그램이 명시적으로 요청하기 전에 미래에 필요할 것으로 예상되는 데이터나 코드를 물리 메모리로 미리 적재하는 기법이다. 이는 요구 페이징 시스템에서 발생하는 페이지 폴트의 빈도를 줄여 성능을 향상시키는 데 목적이 있다. 예측은 공간 지역성과 시간 지역성의 원칙을 바탕으로 이루어진다. 대표적인 방법으로는, 한 페이지에 접근할 때 인접한 다음 페이지를 미리 읽어오는 순차 프리페칭이 있다. 더 복잡한 알고리즘은 프로그램의 접근 패턴을 학습하거나 힌트를 사용하여 예측 정확도를 높이기도 한다.
쓰레싱은 시스템이 실제 유용한 작업보다 페이지 교체에 대부분의 시간을 소비하여 처리량이 급격히 떨어지는 상태를 말한다. 이는 실행 중인 프로세스들이 필요로 하는 최소한의 페이지 프레임 수보다 할당된 프레임이 적을 때 발생한다. 각 프로세스가 지속적으로 페이지 폴트를 발생시키면, 운영체제는 다른 프로세스의 페이지를 교체해야 하고, 이로 인해 해당 프로세스도 곧 페이지 폴트를 내며 악순환이 반복된다.
쓰레싱을 해결하거나 완화하기 위한 주요 방안은 다음과 같다.
방안 | 설명 |
|---|---|
작업 집합 모델 적용 | 프로세스가 일정 시간 동안 접근한 페이지들의 집합인 작업 집합을 유지하며, 해당 집합이 메모리에 상주하도록 보장한다. |
페이지 폴트 빈도 기반 조정 | 페이지 폴트 발생률을 모니터링하여 그 비율이 너무 높으면 프로세스에 더 많은 프레임을 할당하고, 너무 낮으면 프레임을 회수한다. |
로컬 교체 알고리즘 사용 | 페이지 교체 시 동일 프로세스에게 할당된 프레임 내에서만 교체를 수행하여, 한 프로세스의 행위가 다른 프로세스에 영향을 미치지 못하게 한다. |
작업 수 제한 | 시스템에 동시에 적재되는 다중 프로그래밍 정도를 조절하여, 메모리 요구량이 물리 메모리 용량을 초과하지 않도록 한다. |
이러한 기법들은 메모리 관리 시스템의 효율성을 극대화하고, 사용자에게 더 나은 응답 시간과 처리량을 제공하는 데 기여한다.
페이지 프리페칭은 메모리 관리 성능을 향상시키기 위해, 프로세스가 실제로 요청하기 전에 미래에 필요할 것으로 예상되는 페이지를 미리 물리 메모리로 불러들이는 기법이다. 이 기법은 요구 페이징 시스템에서 빈번하게 발생하는 페이지 폴트로 인한 성능 저하를 완화하는 데 목적이 있다. 프로그램의 실행은 지역성의 원리, 특히 공간 지역성에 따라 이루어지는 경우가 많기 때문에, 현재 접근 중인 페이지 근처의 페이지를 미리 읽어오는 것이 효과적이다.
프리페칭의 효과는 예측 정확도에 크게 의존한다. 잘못된 예측으로 불필요한 페이지를 읽어오면, 입출력 버스 대역폭을 낭비하고 실제 필요한 작업을 위한 페이지를 쫓아낼 위험도 있다. 주요 프리페칭 전략으로는 공간 지역성을 활용한 인접 페이지 프리페칭, 프로그램 실행 흐름을 분석하는 소프트웨어 기반 프리페칭, 그리고 하드웨어가 메모리 접근 패턴을 학습하여 예측하는 하드웨어 프리페칭 등이 있다.
프리페칭 유형 | 설명 | 장점 | 단점 |
|---|---|---|---|
인접 페이지 프리페칭 | 현재 페이지와 인접한 하나 이상의 페이지를 미리 읽어옴 | 구현이 간단하고 공간 지역성이 높은 경우 효과적 | 순차적이지 않은 접근 패턴에서는 성능 저하 유발 |
소프트웨어 기반 프리페칭 | 컴파일러나 프로그래머가 코드에 프리페칭 힌트 명령어 삽입 | 프로그램 의미를 이해하여 정확한 예측 가능 | 애플리케이션 수정 필요, 이식성 제한 |
하드웨어 기반 프리페칭 | MMU나 메모리 컨트롤러가 접근 패턴(스트라이드)을 학습하여 예측 | 투명성 높음, 소프트웨어 변경 불필요 | 하드웨어 복잡도 증가, 학습에 따른 오버헤드 |
효과적인 프리페칭은 페이지 폴트율을 낮추고 CPU 이용률을 높여 전체 시스템 처리량을 증가시킨다. 특히 대용량 데이터를 순차적으로 처리하는 과학 계산이나 멀티미디어 애플리케이션에서 성능 향상 효과가 두드러진다. 그러나 프리페칭 정책은 쓰레싱을 유발하지 않도록 페이지 교체 알고리즘 및 시스템의 여유 프레임 수와 함께 고려되어야 한다.
쓰레싱은 시스템이 실제 작업보다 페이지 교체에 대부분의 시간을 소비하여 처리량이 급격히 떨어지는 현상을 말한다. 이는 요구 페이징 시스템에서 활발히 사용되는 페이지 수가 사용 가능한 물리 프레임 수를 초과할 때 발생한다. 각 프로세스가 실행에 필요한 최소한의 프레임을 할당받지 못하면, 페이지 폴트가 빈번하게 일어나고, 이로 인해 디스크 입출력이 증가하며 CPU 이용률은 낮아진다. 운영체제는 CPU 이용률이 낮아지면 다중 프로그래밍의 정도를 높이는 방식으로 대응하는데, 이는 더 많은 프로세스를 메모리에 올려 쓰레싱을 더욱 악화시키는 악순환을 초래한다.
쓰레싱을 탐지하고 완화하기 위한 주요 방안은 다음과 같다.
* 작업 집합 모델(Working Set Model): 프로세스가 일정 시간 동안 참조한 페이지들의 집합인 작업 집합을 유지한다. 운영체제는 각 프로세스의 작업 집합이 메모리에 상주하도록 보장하며, 작업 집합이 할당된 프레임을 초과하면 프로세스를 일시 중단시킨다.
* 페이지 폴트 빈도(Page-Fault Frequency, PFF): 각 프로세스의 페이지 폴트 발생률을 모니터링한다. 페이지 폴트율이 상한 임계값을 넘으면 프로세스에 더 많은 프레임을 할당하고, 하한 임계값보다 낮으면 프레임을 회수하여 할당을 동적으로 조정한다.
탐지/완화 기법 | 주요 원리 | 목적 |
|---|---|---|
작업 집합 모델 | 시간 간격 Δ 동안 참조된 페이지 집합을 유지 | 프로세스에 필요한 최소 프레임 수를 보장 |
페이지 폴트 빈도(PFF) | 페이지 폴트 발생률을 상/하한 임계값과 비교 | 프레임 할당을 동적으로 조정 |
로컬 교체 정책 | 프로세스별로 프레임 풀을 고정하고, 해당 풀 내에서만 페이지 교체 | 한 프로세스의 과도한 페이지 폴트가 다른 프로세스에 영향을 미치지 않도록 차단 |
또한, 페이지 교체 알고리즘을 로컬 교체 정책으로 변경하는 것도 효과적이다. 로컬 교체 정책은 각 프로세스에 고정된 수의 프레임을 할당하고, 해당 프로세스의 페이지 폴트는 자신에게 할당된 프레임 풀 내에서만 교체가 일어나도록 한다. 이렇게 하면 한 프로세스의 비정상적인 페이지 요구가 시스템 전체의 프레임을 독점하여 다른 프로세스를 방해하는 것을 막을 수 있다. 결국 쓰레싱의 근본적인 해결책은 시스템의 다중 프로그래밍 정도를 낮추거나, 물리 메모리를 추가하는 것이다.
리눅스 커널의 메모리 관리는 가상 메모리와 페이징을 기반으로 한 복잡한 계층적 구조를 가진다. 물리 메모리는 페이지 프레임 단위로 관리되며, 커널은 버디 할당자와 슬랩 할당자를 결합하여 효율적인 메모리 할당과 단편화 방지를 수행한다[7]. 사용자 프로세스의 가상 주소 공간은 코드, 데이터, 힙, 스택 등의 세그먼트로 구성되며, 각 프로세스는 독립적인 페이지 테이블을 가진다. 리눅스는 요구 페이징 방식을 사용하여 실제 필요한 페이지만 물리 메모리에 적재하고, 페이지 캐시를 통해 파일 I/O 성능을 극대화한다.
마이크로소프트 윈도우 운영 체제의 가상 메모리 구현은 프로세스별 4GB(32비트 기준)의 가상 주소 공간을 제공한다. 이 공간은 하위 2GB는 사용자 모드, 상위 2GB는 커널 모드용으로 예약되는 것이 일반적이다. 윈도우의 메모리 관리자는 요구 페이징과 클러스터링 기법을 사용하여 페이지 폴트를 줄이고 성능을 개선한다. 페이지 교체 정책으로는 변형된 LRU 알고리즘을 사용하며, 물리 메모리가 부족해지면 작업 집합 관리자가 활성화되어 페이지를 페이징 파일로 내보낸다.
두 시스템의 주요 구현 차이점은 다음과 같다.
특성 | 리눅스 커널 | 마이크로소프트 윈도우 |
|---|---|---|
기본 페이지 크기 | 4KB (대부분의 아키텍처) | 4KB (x86/x64) |
페이지 교체 알고리즘 근사 | CLOCK 알고리즘 변형 | 변형 LRU (작업 집합 기반) |
페이지 캐시 역할 | 파일 데이터와 익명 메모리 통합 관리 | 시스템 캐시와 작업 집합으로 분리 |
대용량 메모리 지원 | Huge Page 지원 (2MB, 1GB) | Large Page 지원 (2MB) |
페이징 파일/스왑 | 하나 이상의 독립적인 스왑 영역/파일 사용 | 하나의 페이징 파일(기본) 또는 여러 개 사용 가능 |
이러한 설계 차이는 각 운영 체제의 철학과 목표에 기인한다. 리눅스는 유연성과 다양한 하드웨어 플랫폼 이식성에 중점을 두는 반면, 윈도우는 데스크톱 및 서버 환경에서의 응답성과 호환성에 최적화되어 있다. 두 시스템 모두 TLB 미스와 페이지 폴트를 최소화하기 위해 지속적으로 메모리 관리 알고리즘을 발전시켜 왔다.
리눅스 커널의 메모리 관리는 가상 메모리와 페이징을 기반으로 한 복잡한 계층적 구조를 가진다. 커널은 4단계 또는 5단계의 페이지 테이블 계층을 사용하여 64비트 시스템의 방대한 주소 공간을 관리한다[8]. 물리 메모리는 '페이지 프레임'이라는 단위로 관리되며, 커널은 struct page 자료 구조를 통해 각 프레임의 상태를 추적한다. 메모리 할당 요청은 크기와 용도에 따라 '슬랩 할당자', '페이지 할당자(buddy 시스템)' 등 서로 다른 할당자 계층을 통해 처리된다.
사용자 프로세스의 관점에서, 리눅스는 각 프로세스에 독립적인 가상 주소 공간을 제공한다. 이 공간은 코드, 데이터, 힙, 스택, 메모리 매핑 영역 등으로 구성된다. mmap() 시스템 호출을 통한 파일 매핑이나 공유 메모리 영역 생성이 가능하다. 커널은 프로세스별 페이지 테이블을 유지하며, MMU와 TLB의 도움을 받아 가상 주소를 물리 주소로 변환한다.
리눅스는 요구 페이징 방식을 채택하여, 프로세스가 실제로 접근하는 페이지만 물리 메모리에 적재한다. 페이지 부재가 발생하면 커널은 페이지 폴트 핸들러를 실행하여 디스크에서 해당 페이지를 읽어온다. 물리 메모리가 부족해지면 커널의 'kswapd' 데몬이 백그라운드에서 활성화되어, 페이지 교체 알고리즘을 기반으로 사용 빈도가 낮은 페이지를 선별해 디스크의 스왑 영역으로 내보낸다. 리눅스는 LRU(Least Recently Used) 접근법의 변형을 사용하여 페이지를 교체한다.
성능 최적화를 위해 리눅스는 여러 기법을 적용한다. 파일 접근의 지역성을 활용한 '페이지 캐시'는 디스크 I/O를 줄이는 핵심 매커니즘이다. '투명한 대용량 페이지' 지원을 통해 특정 조건에서 더 큰 페이지 단위로 메모리를 관리하여 TLB 미스율을 낮출 수 있다. 또한, 메모리 압축 기법을 도입하여 스왑 아웃보다 빠르게 메모리 공간을 확보하기도 한다.
윈도우 운영 체제는 가상 메모리 시스템을 통해 각 프로세스에게 독립적인 4GB(32비트 시스템 기준)의 가상 주소 공간을 제공한다. 이 공간은 사용자 모드 공간(하위 2GB 또는 3GB)과 커널 모드 공간(상위 2GB 또는 1GB)으로 나뉜다. 가상 주소에서 물리 메모리 주소로의 변환은 MMU(Memory Management Unit)와 페이지 테이블을 통해 이루어지며, 성능 향상을 위해 TLB(변환 색인 버퍼)를 적극 활용한다.
주요 구성 요소로는 프로세스별 가상 주소 공간을 관리하는 '가상 메모리 관리자'(Virtual Memory Manager)와 실제 물리 페이지의 할당 및 상태를 추적하는 '물리 메모리 관리자'가 있다. 디스크 상의 페이징 파일(pagefile.sys)은 물리 메모리가 부족할 때 사용되지 않는 페이지를 저장하는 백업 저장소 역할을 한다. 윈도우는 요구 페이징 방식을 사용하여, 프로세스가 처음 시작될 때 모든 코드와 데이터를 메모리에 로드하지 않고, 실제로 접근이 발생하는 페이지만 물리 메모리로 불러온다.
페이지 교체 정책은 변형된 LRU(최근 최소 사용) 알고리즘에 기반한다. 시스템은 물리 메모리의 페이지들을 '활성' 목록과 '비활성' 목록으로 관리하며, 메모리가 부족해지면 비활성 목록의 페이지들을 먼저 페이징 파일로 내보낸다. 또한, '메모리 압축' 기능(윈도우 10부터)을 도입하여 일부 페이지를 디스크에 쓰기 전에 메모리 내에서 압축하여 입출력 오버헤드를 줄이고 성능을 개선했다.
구성 요소 | 설명 |
|---|---|
가상 메모리 관리자 | |
물리 메모리 관리자 | 물리 메모리 프레임의 할당/해제 및 상태 추적 |
페이징 파일(pagefile.sys) | 물리 메모리의 확장 영역으로 사용되는 디스크 공간 |
작업 집합(Working Set) | 프로세스가 현재 물리 메모리에 유지하고 있는 페이지들의 집합 |
메모리 압축 | 페이지를 디스크로 내보내기 전 메모리에서 압축하여 저장하는 기술 |
시스템 성능을 위해 윈도우는 '페이지 프리페칭'과 '슈퍼페치' 기술을 사용한다. 페이지 프리페칭은 프로세스 시작 시 예측하여 필요한 페이지를 미리 메모리로 가져오고, 슈퍼페치는 사용자의 애플리케이션 사용 패턴을 학습하여 자주 사용되는 데이터를 미리 캐시한다. 이러한 구현 방식은 애플리케이션의 응답 속도를 높이고, 쓰레싱 현상을 완화하는 데 기여한다.