배경
지금까지는 CPU를 중점으로 프로세스들이 CPU를 어떻게 나눠 가지냐를 다뤘다면, 이제부터는 메모리에 프로세스를 어떻게 배치하고 관리할지에 대해서 학습
메모리 할당(Allocation)
Contiguous Memory Allocation
- 정의: 한 프로세스를 메모리상에 연속적인 위치에 할당하는 방법 - 간단한 방법
- 즉, 프로세스를 한 덩어리채로 메모리에 할당한다는 것
- 방법: 메모리의 어느 부분이 비어있는지에 대한 정보(free-block list)를 통해 프로세스를 할당
- Dynamic 프로세스를 빈 공간(hole)에 넣는 3가지 전략
- First-Fit: 프로세스를 넣을 수 있는 첫번째 hole에 할당하는 전략
- Best-Fit: 프로세스를 넣을 수 있는 공간 중에 가장 작은 hole에 할당하는 전략
- Worst-Fit: 프로세스를 넣을 수 있는 공간 중에 가장 큰 hole에 할당하는 전략
- 문제점: 단편화(Fragmentation) 발생
- 외부 Fragmentation 문제: 이렇게 빈 공간에 연속적으로 넣게 되면 조그만 한 빈 공간(fragmentation)이 여러개가 발생
- 그러면 나중에 A프로세스가 들어갈 메모리 공간은 아직 남아있는데 연속적으로 넣을 공간은 안생기는 문제 발생
- 내부 Fragmentation 문제: 한 파티션 내의 빈 공간
- 만약 파티션 단위가 10인데 마지막에 3만 차있는 경우 -> 7의 내부 fragmentation이 발생한 것
- 외부 Fragmentation 문제: 이렇게 빈 공간에 연속적으로 넣게 되면 조그만 한 빈 공간(fragmentation)이 여러개가 발생
Paging
- 정의: 한 프로세스를 메모리에 연속적이지 않게 배치하는 방법
- 즉, 프로세스를 쪼개서 메모리에 할당하는 방법
- 조각 단위:
- 물리적 메모리 주소를 고정된 사이즈의 블록(프레임)으로 나눈다
- 논리적 메모리 주소를 고정된 사이즈의 블록(페이지)로 나눈다
- 사용 방법: CPU는 이제 2개의 logical address 정보를 가지고 접근
- Page number(p): n번째 페이지에 대한 정보
- Page offset(d): n번째 페이지의 k번째 코드에 대한 정보
동작 과정1 | 동작 과정2 |
![]() |
![]() |
- 동작 과정1: 새로운 프로세스가 도착했을 때, 메모리에 어떻게 로드되는가?
- 프로세스를 n개의 페이지 단위로 나눈다.
- 메모리의 빈 공간(free-frame 리스트)을 보고, 각 page number를 frame number에 배치
- 배치 후 page table을 생성 ( 구조 - page number : frame number )
- 동작 과정2: cpu가 logical 주소를 가지고 실제 메모리에 접근하는 과정
- Page number(p)를 가지고 page table에 접근
- page table에서 해당 p에 매핑되는 frame number(f)를 접근
- f를 가지고 메모리에 접근하고 offset크기만큼 더해서 접근 ( f + d )
- 장점:
- 외부 fragmentation문제를 해결 가능
- Swaping이 간단하다.
- 코드를 쉽게 공유 할 수 있다.(Shared pages)
- 여러 프로세스에서 사용하는 공유 라이브러리를 공유 페이지로 만들어서 사용하자는 것 ( printf() 같은 라이브러리들.. )
- 단점:
- 내부 단편화를 해결하지 못함
- Page table을 저장하기 위해 메모리가 추가로 소모
- 실제 메모리에 접근하기 위해 Page table을 접근해야하기 때문에 속도가 느림 -> TLB
페이지 사이즈
- 페이지 사이즈는 2^n 이여야 한다. (보통 4kb ~ 1GB)
- 그러면 메모리 공간이 2^m이고, 페이지 사이즈가 2^n 이면
- page number에 필요한 비트 수 = m - n
- page offset에 필요한 비트 수 = n
- 예시) page 크기 = 4KB(2^12), 메모리 크기 = 4GB(2^32) -> 총 가질 수 있는 Page Table의 Entry수 = 2^(32-12)
그러면 코드가 엄청 길어서 프로세스 크기가 크다면 페이지 사이즈를 어떻게 하는 것이 좋은가?
페이지 사이즈 작음 | 페이지 사이즈 큼 | |
내부 frgmentation 문제 | 작음 | 큼 |
한 페이지 로드 시간 | 짧음 | 김 |
페이지 테이블 크기 | 큼 | 작음 |
페이지 테이블 위치
MM & PTBR
- 페이지 테이블은 프로세스마다 존재하며 메인 메모리에 상주한다.
- 페이지 테이블은 대부분 매우 크기에 Register를 사용하여 처리하는 것은 적절x
- PTBR(Page-table base register)(HW 솔루션): MM에 있는 페이지 테이블의 시작 주소만을 저장하는 레지스터
- 문맥 교환(Context switch)가 발생하는 경우, 해당 레지스터 내용 활용
-> 페이지 테이블이 MM에 있기에 실제 메모리 접근을 위해 2번 접근을 해야하는 성능 문제 발생 ( 단점3 )
TLB(Translation Look-aside Buffer)
- TLB(Translation Look-aside Buffer): 페이징 성능 개선을 위해 MM에 있는 Page 테이블 정보에 대한 캐시를 만들자!
- TLB는 Page Num과 Frame Num을 동시에 가지고 있는 구조
- TLB hit: 접근하고자 하는 Page number가 TLB안에 있는 경우
- TLB miss: TLB안에 없는 경우
메모리 보호
- 그러면 다른 프로세스 영역을 침범하지 않기 위해서 어떻게 해줘야하지?
- valid-invalid bit: 하나의 추가적인 비트를 사용해서 해당 프로세스 영역인지 확인
Segmentation
- 정의: 의미 단위로 하나의 프로세스를 나누는 방식
- 일반적으로 code, data, stack 부분이 하나의 세그먼트로 정의
참고
https://rebro.kr/178?category=504670
[운영체제(OS)] 8. 메모리 관리(Memory Management)
[목차] 1. Address Binding 2. Swapping 3. Contiguous Allocation 4. Fragmentation 5. Paging 6. Translation Look-aside Buffer 7. Structure of the Page Table 8. Segmentation 참고) - https://parksb.github.io/article/12.html - KOCW 공개강의 (2014-1. 이
rebro.kr
'CS > 운영체제' 카테고리의 다른 글
[OS] 파일 시스템(File System) (0) | 2024.09.02 |
---|---|
[OS] 가상 메모리 (0) | 2024.09.02 |
[OS] 데드락 (0) | 2024.09.02 |
[OS] 프로세스 동기화(세마포어와 뮤텍스) (1) | 2024.09.02 |
[OS] CPU 스케줄링 (1) | 2024.09.02 |