페이징과 세그먼테이션 – 프로그램이 메모리를 쓰는 실제 방식

fragmentation 사진


운영체제 과목에서 처음 '페이징'이라는 개념을 배웠을 때, 단순히 주소를 쪼개는 기법이라고만 이해했습니다. 그러나 가상 메모리를 구현하는 과정에서 실제로 페이지 테이블을 구성하고, 주소 변환을 해보는 실습을 거치면서 이 개념이 단순히 이론이 아니라 시스템 안정성과 효율성에 직결된다는 사실을 체감할 수 있었습니다.

가상 메모리의 필요성과 메모리 관리의 기본

현대 운영체제는 여러 프로그램이 동시에 실행되는 멀티태스킹 환경을 제공합니다. 이때 각 프로그램은 독립된 주소 공간을 사용하는 것처럼 동작하지만, 실제로는 하나의 물리 메모리를 공유합니다. 이러한 환경을 안전하고 효율적으로 운영하기 위해 운영체제는 ‘가상 메모리(Virtual Memory)’를 사용하며, 이를 구현하는 대표적인 방식이 바로 페이징(Paging)과 세그먼테이션(Segmentation)입니다.

가상 메모리의 핵심은, 실제 메모리의 물리적 주소를 사용자 프로그램이 직접 알지 못하도록 하면서, 필요한 메모리 영역만을 선택적으로 메모리에 올리는 것입니다. 이를 통해 메모리 공간을 효율적으로 활용할 수 있으며, 각 프로세스의 독립성과 보안성도 확보할 수 있습니다. 이 과정에서 논리 주소(Logical Address)를 물리 주소(Physical Address)로 변환하는 구조가 필요한데, 이때 사용되는 기법이 바로 페이징과 세그먼테이션입니다.

페이징(Paging) – 고정 크기 단위로 나누기

페이징은 주소 공간을 고정된 크기의 블록으로 나누는 방식입니다. 프로그램이 사용하는 논리 주소 공간은 ‘페이지(Page)’라는 단위로 나뉘며, 실제 물리 메모리도 같은 크기의 ‘프레임(Frame)’으로 분할됩니다. 그리고 페이지와 프레임 간의 매핑 정보는 운영체제가 관리하는 **페이지 테이블(Page Table)**에 저장됩니다.

예를 들어, 페이지 크기가 4KB이고, 논리 주소가 16KB라고 가정하면, 이 주소 공간은 4개의 페이지로 분할됩니다. 운영체제는 이 4개의 페이지를 물리 메모리의 임의의 4개 프레임에 할당하고, 각 페이지가 어느 프레임에 매핑되었는지를 페이지 테이블에 기록합니다. 프로그램은 논리 주소만 인식하며, 실제 물리 주소는 하드웨어(MMU)가 자동으로 변환해줍니다.

페이징의 가장 큰 장점은 외부 단편화(External Fragmentation)를 줄일 수 있다는 것입니다. 모든 페이지와 프레임이 동일한 크기이기 때문에, 메모리를 할당할 때 빈 공간을 효율적으로 사용할 수 있습니다. 반면, 페이지 크기보다 작은 데이터가 저장되면 사용되지 않는 공간이 생길 수 있으며, 이를 내부 단편화(Internal Fragmentation)라고 부릅니다.

현대 운영체제에서는 2단계 혹은 다단계 페이지 테이블을 사용하여, 큰 주소 공간을 더 효율적으로 관리합니다. 또한, 페이지 테이블 자체가 커질 경우, 이를 메모리에 모두 상주시킬 수 없기 때문에 TLB(Translation Lookaside Buffer)라는 캐시 구조를 사용하여 주소 변환 속도를 높이는 방식도 병행됩니다.

세그먼테이션(Segmentation) – 의미 기반의 메모리 분할

세그먼테이션은 주소 공간을 의미 단위로 나누는 방식입니다. 프로그램을 실행할 때 코드, 데이터, 스택 등 각 영역을 별도의 세그먼트(Segment)로 구분하여 관리합니다. 각 세그먼트는 크기가 유동적이며, 그 의미에 따라 다른 권한이나 속성을 가질 수 있습니다.

예를 들어, 하나의 프로그램이 코드 세그먼트(읽기/실행 가능), 데이터 세그먼트(읽기/쓰기 가능), 스택 세그먼트(읽기/쓰기, 크기 가변)로 나뉘어져 있다고 가정하면, 각 세그먼트는 시작 주소(base)와 길이(limit)를 가지고 운영체제에 의해 관리됩니다. 논리 주소는 (세그먼트 번호, 오프셋) 형태로 표현되며, 하드웨어는 이를 물리 주소로 변환합니다.

세그먼테이션의 장점은 프로그래머에게 논리적 구조와 메모리 보호를 제공한다는 점입니다. 예를 들어, 코드 세그먼트에는 쓰기 권한이 없기 때문에 잘못된 쓰기 연산을 차단할 수 있습니다. 또한 각 세그먼트를 독립적으로 관리할 수 있어, 메모리 접근 오류를 방지하는 데 유리합니다.

하지만 세그먼테이션은 고정된 크기가 아니기 때문에, 메모리 할당이 반복될수록 사용되지 않는 작은 공간들이 남게 되는 외부 단편화 문제가 발생할 수 있습니다. 이러한 문제를 해결하기 위해, 일부 시스템은 세그먼테이션과 페이징을 결합한 세그먼트-페이징(Segmented Paging) 구조를 사용합니다.

즉, 세그먼트 내부를 다시 페이지 단위로 나누어, 의미 기반 관리의 유연성과 페이징의 메모리 활용 효율성을 동시에 확보하는 방식입니다. 이는 현대 운영체제에서 널리 채택되고 있는 설계입니다.

결론 – 메모리 관리는 시스템 안정성의 기반

페이징과 세그먼테이션은 단순한 이론이 아닌, 운영체제가 실제로 메모리를 관리하고 프로그램을 실행하는 핵심 구조입니다. 이들을 이해하면, 프로그램이 어떻게 메모리에 올라가고, 어떤 방식으로 자원을 사용하는지를 보다 명확하게 알 수 있습니다.

메모리 오류, 보안 취약점, 성능 병목 등의 문제도 결국 이 구조를 이해함으로써 근본적인 원인을 파악할 수 있습니다. 개발자와 시스템 엔지니어라면 반드시 이 개념들을 숙지하고, 실제 시스템에서 어떻게 활용되고 있는지까지 깊이 있게 접근할 필요가 있습니다.

댓글

이 블로그의 인기 게시물

지도학습 vs 비지도학습 – 머신러닝의 대표 학습 방식 비교

모델 평가 지표 정리 – 정확도, 정밀도, F1 Score까지

선형회귀와 로지스틱 회귀 – 가장 기초적인 예측 모델들