[인프런 워밍업 클럽 스터디 3기] CS - 3주차 발자국
이번 주차에 가상 메모리를 배우며 정말 흥미를 느꼈습니다.
사람들이 주어진 메모리 안에서 최대한 활용하기 위해 엄청 노력하여 만들어낸 여러 기술들을 보며 재밌게 공부한 한 주 였습니다.
메모리의 종류와 주소 체계
1. 메모리의 종류
컴퓨터에서 사용되는 주요 메모리는 다음과 같이 구분된다.
1.1 레지스터 (Register)
CPU 내부에 위치하며 가장 빠른 기억장소
전원 차단 시 데이터가 사라지는 휘발성 메모리
CPU의 비트 수(예: 32비트, 64비트)는 레지스터의 크기를 의미
CPU는 연산 시 메인메모리(RAM)의 데이터를 레지스터로 가져와 계산 후 다시 메인메모리에 저장
1.2 캐시 메모리 (Cache Memory)
레지스터보다 느리지만 메인메모리보다 빠른 휘발성 메모리
메인메모리 접근 속도를 개선하기 위해 사용
CPU가 자주 사용할 것 같은 데이터를 미리 저장해 속도 차이를 줄임
성능 향상을 위해 여러 단계(L1, L2 캐시 등)로 구성됨
1.3 메인메모리 (RAM, Random Access Memory)
운영체제와 프로세스가 실행되는 공간
전원이 꺼지면 데이터가 사라지는 휘발성 메모리
프로그램 실행 및 데이터 처리 속도에 직접적인 영향을 줌
1.4 보조 저장장치 (HDD, SSD)
전원이 차단되어도 데이터가 유지되는 비휘발성 메모리
하드디스크(HDD)는 비교적 저렴하지만 속도가 느림
솔리드스테이트드라이브(SSD)는 빠르지만 가격이 높음
2. 메모리와 주소 체계
운영체제는 메모리를 효과적으로 관리하기 위해 1바이트 단위로 구역을 나누고 각 구역에 **주소(Address)**를 부여한다.
2.1 32비트 vs 64비트 CPU
32비트 CPU
레지스터 크기: 32비트
연산 장치(ALU), 데이터 버스도 32비트
다룰 수 있는 메모리 크기: 2^32=4GB
64비트 CPU
레지스터 크기: 64비트
연산 장치(ALU), 데이터 버스도 64비트
다룰 수 있는 메모리 크기 : 2^64 (거의 무한대)
2.2 물리 주소와 논리 주소
물리 주소 공간: 메모리를 실제로 연결하면 0x0번지부터 시작하는 주소 공간
논리 주소 공간: 운영체제가 사용자 프로그램을 위해 제공하는 가상의 주소 공간
사용자는 논리 주소만 인식하며, 운영체제가 이를 물리 주소로 변환
운영체제 보호를 위해 **경계 레지스터(Boundary Register)**를 사용하여 프로세스가 메모리 접근 시 경계를 넘지 않도록 관리함
2.3 절대 주소 vs 상대 주소
절대 주소 (Absolute Address): 실제 메모리에서 사용되는 물리 주소
상대 주소 (Relative Address): 프로그램이 실행될 때 기준이 되는 시작 주소를 기반으로 한 주소
프로그램 실행 시 **재배치 레지스터(Relocation Register)**를 사용해 논리 주소를 절대 주소로 변환
2.4 메모리 주소 변환 예시
사용자가 논리 주소
0x100의 데이터를 요청CPU가 메모리 관리자에게
0x100번지 데이터를 요청메모리 관리자는 **재배치 레지스터 값(예:
0x4000)**을 더해 **절대 주소0x4100*의 데이터를 가져옴프로그램 시작 주소가 변경되더라도 재배치 레지스터 값만 수정하면 됨
메모리 할당 방식
과거 유니프로그래밍 환경에서는 메모리보다 큰 프로그램을 실행할 때 필요한 부분만 메모리에 올리고, 나머지는 하드디스크에 저장하는 메모리 오버레이 기법을 사용했다. 이를 통해 큰 프로그램을 여러 조각으로 나누어 일부만 실행하며, 나머지는 하드디스크의 스왑 영역에 저장했다.
현대의 멀티프로그래밍 환경에서는 메모리 할당 방식이 **가변 분할 방식(세그멘테이션)**과 **고정 분할 방식(페이징)**으로 나뉜다.
1. 가변 분할 방식 (세그멘테이션)
프로세스의 크기에 따라 메모리를 동적으로 나누는 방식
하나의 프로세스가 메모리에 연속된 공간에 할당됨 (연속 메모리 할당)
✅ 장점
낭비되는 공간인 내부 단편화가 발생하지 않음
❌ 단점
외부 단편화가 발생할 수 있음
2. 고정 분할 방식 (페이징)
프로세스의 크기와 관계없이 일정한 크기의 블록(페이지)로 나누어 메모리에 할당
하나의 프로세스가 메모리 내 비연속적인 공간에 할당됨 (비연속 메모리 할당)
✅ 장점
구현이 간단하고 오버헤드가 적음
❌ 단점
사용되지 않는 공간이 발생하여 내부 단편화가 많음
메모리 단편화 문제와 해결 방법
외부 단편화
프로세스가 종료된 후 남은 메모리가 조각나서, 새로운 프로세스가 올라갈 수 없는 현상
해결 방법: **조각 모음(Compaction)**을 통해 단편화된 메모리 공간을 정리
하지만 조각 모음 과정에서 오버헤드(추가적인 연산 비용)가 발생
내부 단편화
프로세스 크기보다 큰 고정된 메모리 블록을 할당하면서 사용되지 않는 공간이 생기는 현상
해결 방법:
할당되는 블록 크기를 조정하여 내부 단편화를 최소화
버디 시스템을 사용하여 효율적인 메모리 할당
버디 시스템
2의 승수 단위로 메모리를 분할하여 할당하는 방식
프로세스의 요청 크기에 가장 적합한 크기의 블록을 할당하여 외부 단편화를 방지
하지만 내부 단편화는 일부 발생할 수 있음
예시
2048B(2^11)의 메모리가 있음
500B 크기의 프로세스 A가 메모리를 요청
512B(2^9) 크기의 블록을 할당
이처럼 프로세스 크기에 맞게 할당되며, 불필요한 공간 낭비를 줄일 수 있음.
현대의 메모리 관리 방식
현재는 가변 분할(세그멘테이션)과 고정 분할(페이징) 방식을 조합하여 사용한다.
이를 통해 내부·외부 단편화 문제를 최소화하면서도 효율적인 메모리 활용이 가능하다.
가상 메모리 정리
운영체제나 프로세스가 4GB 메모리 환경에서 동작하도록 설계되었다면, 그보다 적은 메모리에서는 실행되지 않는 문제가 발생할 수 있음.
→ 가상 메모리(Virtual Memory) 를 사용하면 이 문제를 해결 가능.
가상 메모리 개념
프로세스는 메모리 관리자를 통해 메모리에 접근하며, 물리 메모리에 직접 접근하지 않음.
가상 메모리의 크기는 이론적으로 무한대이나, 실제로는 물리 메모리 크기와 CPU의 bit 수에 의해 제한됨.
예시: 32bit CPU → 2³² = 약 4GB가 최대 가상 메모리 크기.
가상 메모리의 동작 방식
운영체제를 포함하여 총 4GB 용량의 프로세스들이 실행되는 경우를 가정하면:
필요한 메모리보다 물리 메모리가 부족할 수 있음.
가상 메모리 시스템은 사용하지 않는 일부 데이터를 하드디스크의 스왑 영역으로 이동함.
실행이 필요할 때 해당 데이터를 다시 물리 메모리로 불러와 실행 → 모든 프로세스가 실행 가능.
📌 동적 주소 변환 (Dynamic Address Translation)
메모리 관리자는 가상 주소(Virtual Address) 와 물리 주소(Physical Address) 를 매핑하여 변환함.
즉, 물리 메모리와 스왑 영역을 합쳐 가상의 주소 공간을 제공.
메모리 관리자의 역할
메모리 관리자는 다음과 같은 복잡한 문제를 처리함.
물리 메모리를 어떻게 나눌지
프로세스를 어디에 배치할지
부족한 물리 메모리를 어떻게 처리할지
가상 메모리 시스템의 할당 방식
운영체제는 자신의 영역을 제외한 나머지 메모리를 일정한 크기로 나누어 프로세스에 할당함.
📌 메모리 분할 방식:
고정 분할 (Fixed Partitioning)
가변 분할 (Variable Partitioning)
세그멘테이션 (Segmentation)
페이징 (Paging)
각각의 단점을 보완하기 위해 세그멘테이션-페이징 혼합 기법도 사용함.
가상 주소와 물리 주소 매핑
가상 메모리 시스템에서 가상 주소는 실제로 메모리 또는 스왑 영역 중 한 곳에 존재함.
메모리 관리자는 가상 주소와 물리 주소를 1:1 매핑 테이블로 관리하여 변환을 수행.
📌 2강: 세그멘테이션 정리
🔹 세그멘테이션 개념
세그멘테이션에서 프로그램은 함수나 모듈 등으로 세그먼트를 구성한다.
즉, 프로그램을 구성하는 논리적인 단위(코드, 데이터, 힙, 스택 등)를 개별적인 세그먼트로 관리한다.
각 세그먼트끼리는 반드시 인접할 필요가 없다.
🔹 논리 주소 vs 물리 주소
프로세스가 바라보는 메모리 구조는 코드, 데이터, 힙, 스택이 연속된 것처럼 보인다.
하지만 실제 물리 메모리에서는 세그먼트들이 흩어져 존재할 수 있다.
CPU와 프로세스가 바라보는 주소를 논리 주소(Logical Address) 라고 한다.
논리 주소를 실제 물리 주소(Physical Address) 로 변환하는 역할을 MMU(메모리 관리 장치) 가 수행한다.
🔹 MMU의 논리 주소 → 물리 주소 변환 과정
1⃣ 세그먼트 테이블(Segment Table) 조회
MMU는 세그먼트 테이블(Segment Table) 을 참고하여 변환을 수행한다.
운영체제가 프로세스 전환(Context Switching)을 할 때마다 MMU의 Segment Table Base Register 값을 변경하여 해당 프로세스의 테이블을 참조하게 한다.
세그먼트 테이블은 다음과 같은 구조를 가진다.
세그먼트 번호 Base Address (기본 주소) Bound Address (크기) 0 1500 500 1 5200 1000 2 3700 1200 3 6400 500
2⃣ 논리 주소 검증
CPU에서 논리 주소를 전달하면, MMU는 해당 주소가 올바른 범위 내에 있는지 확인한다.
Bound Address (세그먼트 크기)와 비교하여,
논리 주소가 Bound Address보다 크면 → 메모리 침범(Out of Bounds) → 인터럽트 발생 & 프로세스 종료
논리 주소가 Bound Address보다 작으면 → 정상적인 접근이므로 변환 진행
3⃣ 물리 주소 변환
Base Address + 논리 주소 = 물리 주소 를 계산하여 변환한다.
🔹 예제: MMU의 주소 변환 과정
예제 요청:
scss
복사편집
MMU야! 세그먼트 1번에서 0x632(= 1586) 번지 요청!
변환 과정:
세그먼트 테이블에서 1번 세그먼트 확인
Base Address =
5200Bound Address =
1000
논리 주소(0x632)가 Bound(1000)보다 작은지 확인
0x632 (1586) < 1000✅ 정상
물리 주소 변환
Base Address + 논리 주소 = 5200 + 1586 = 0x5832 (물리 주소)
3강 📌 페이징 정리
1. 페이징의 개념
외부 단편화를 해결하기 위해 고안된 메모리 관리 기법
메모리를 고정 크기의 페이지(Page) 단위로 나누어 관리
페이지는 논리 주소 공간을 일정한 크기로 나눈 것
물리 메모리도 같은 크기의 블록(Frame) 으로 나누어 페이지를 배치
2. 페이징의 특징
✅ 고정 크기의 페이지이므로 외부 단편화는 발생하지 않음
✅ 하지만 페이지 크기보다 작은 데이터는 내부 단편화를 유발
✅ 논리 주소와 물리 주소 변환을 위해 페이지 테이블(Page Table) 사용
📌 페이징의 동작 원리
1) 논리 주소와 물리 주소 변환
CPU가 논리 주소를 생성하면, MMU(Memory Management Unit) 가 이를 변환
논리 주소는 페이지 번호(Page Number) + 오프셋(Offset) 으로 구성
물리 주소는 프레임 번호(Frame Number) + 오프셋(Offset) 으로 변환
📌 변환 과정
CPU가 논리 주소를 생성
페이지 번호를 이용해 페이지 테이블에서 프레임 번호를 찾음
해당 프레임 시작 주소에 오프셋을 더해 물리 주소 생성
💡 예제
논리 주소:
0x1000(16진수)페이지 크기:
16MB(2^24바이트)
계산 항목 값 페이지 번호 논리 주소 / 페이지 크기 = 0x1000 / 0x1000000 = 0 오프셋 논리 주소 % 페이지 크기 = 0x1000 % 0x1000000 = 0x1000
📌 페이지 테이블 예시
인덱스 (페이지 번호) 프레임 번호 0 3 1 1 2 Invalid … …
📌 물리 주소 계산
페이지 테이블에서 0번 페이지의 프레임 번호는 3
물리 주소 = 3번 프레임 시작 주소 + 0x1000 (오프셋)
📌 페이징 vs 세그멘테이션 비교
구분 페이징 세그멘테이션 메모리 할당 방식 고정 크기로 나눔 논리적 영역(코드, 데이터, 스택 등)으로 나눔 단편화 내부 단편화 발생(페이지 크기보다 작은 데이터) 외부 단편화 발생(세그먼트 크기만큼 연속된 공간 필요) 크기 조정 모든 페이지 크기가 동일(Bound Address 필요 없음) 세그먼트마다 크기 다름(Bound Address 필요) 공유 및 권한 관리 제한적 (페이지 단위로 공유 어려움) 세그먼트 단위로 공유 및 권한 관리 가능 주소 변환 방식 페이지 테이블 사용 (1차원 배열 구조) 세그먼트 테이블 사용 (크기 가변적)
📌 페이징의 단점: 페이지 테이블 크기 관리
각 프로세스마다 페이지 테이블을 가짐 → 프로세스가 많아질수록 테이블도 커짐
페이지 테이블도 물리 메모리(OS 영역)에 저장됨 → 사용자 메모리 공간 감소
해결책: 다단계 페이지 테이블, TLB(Translation Lookaside Buffer) 사용
📌 정리
페이징은 외부 단편화를 없애지만 내부 단편화가 발생할 수 있음
페이지 테이블 크기 관리가 중요한 과제
세그멘테이션과 비교했을 때 공유 및 권한 관리가 더 어렵다
✅ 페이징의 핵심은 효율적인 메모리 관리를 위해 페이지 크기와 페이지 테이블 크기를 적절히 조정하는 것! 🚀
4강: 페이지드 세그멘테이션
1. 개요
페이지드 세그멘테이션은 세그멘테이션과 페이징의 장점을 결합한 메모리 관리 기법이다.
세그멘테이션: 논리적으로 의미 있는 단위(코드, 데이터 등)로 메모리를 나누어 공유 및 접근 보호가 용이함.
페이징: 고정된 크기로 메모리를 분할하여 단편화를 줄이고 효율적으로 관리 가능.
2. 메모리 접근 권한
운영체제는 특정 메모리 번지에 대해 읽기(Read), 쓰기(Write), 실행(Execute) 세 가지 권한을 설정할 수 있다.
예시
0x0000 ~ 0x1000: 읽기 권한만 허용0x1000 ~ 0x2000: 읽기/쓰기 가능
프로세스의 주요 메모리 영역과 권한
메모리 영역 설명 권한 CODE 프로그램 실행 코드 읽기(R), 실행(X) (수정 불가) DATA 전역 변수, 상수 읽기(R), 쓰기(W) 가능 여부 결정 STACK & HEAP 동적 할당된 데이터 읽기(R), 쓰기(W) 가능
메모리 접근 권한은 가상 주소를 물리 주소로 변환할 때마다 검사되며, 위반 시 프로세스가 강제 종료(error) 된다.
3. 페이지드 세그멘테이션 구조
페이지드 세그멘테이션에서는 기존 세그멘테이션 테이블을 확장하여 권한 비트, 페이지 번호, 페이지 개수를 포함한다.
세그멘테이션 테이블
세그먼트 번호 권한 비트 페이지 번호 페이지 개수 0 RW 2 500 1 RE 0 1000 2 R 1 1200 3 RWE n 500
Base Address → 페이지 번호로 변경
Bound Address → 페이지 개수로 변경
권한 비트 추가
페이지 테이블
인덱스 프레임 번호 0 3 1 1 2 Invalid 3 …
4. 가상 주소 변환 과정
가상 주소 예시: 0x12300 번지 접근
세그먼트 번호 확인
MMU Table을 확인 →0x12300번지는 세그먼트 1에 속함세그먼트 1의 정보를 세그멘테이션 테이블에서 가져옴
메모리 접근 권한 검사
세그먼트 1의 권한:
RE(읽기/실행)만약
쓰기(W)요청이라면 → 권한 위반 (Error: 프로세스 종료)읽기/실행 요청이라면 → 다음 단계 진행
페이지 테이블에서 프레임 번호 확인
세그먼트 1의 페이지 번호를 사용해 페이지 테이블을 참조
예: 페이지 테이블에서 프레임 3을 찾음
물리 주소 변환
프레임 3에서 페이지 개수(1000)를 더해 최종 물리 주소 계산
스왑 처리 (필요한 경우)
만약 해당 프레임이 물리 메모리에 없다면 → 디스크(스왑 영역)에서 가져와 메모리에 적재
5. 페이지드 세그멘테이션의 단점
메모리 접근이 2단계로 이루어져 성능 저하 발생 1⃣ 세그멘테이션 테이블 접근 2⃣ 페이지 테이블 접근
이러한 단점 때문에 현대 운영체제는 페이징과 페이지드 세그멘테이션을 적절히 조합하여 사용한다. 🚀
댓글을 작성해보세요.