Segmentaion
: 가상 주소 공간을 세그먼트 단위로 실제 메모리 주소 공간에 독립적으로 각각 매핑하는 방식
1. 정의
Motivation
- 기존 가상 주소 공간에서는 Heap과 Stack 사이의 사용하지 않는 공간도 할당되므로 비효율성이 발생
- 사용하지 않는 크기가 발생하므로 메모리 공간이 낭비됨
- 16KB이상의 메모리가 큰 주소 공간에는 프로세스를 지원할 수 없음
- Code 공간에 여러 코드가 들어가서 중복이 발생할 수 있음
Effect
- 이로 인해 Heap과 Stack 사이의 사용하지 않는 비효율성인 문제를 해결
- 더 이상 메모리 공간이 낭비되지 않음
- 이전보다 훨씬 더 많은 주소 공간을 지원할 수 있음
- 세그먼트는 주소 공간 간에 Code 공간을 공유하면서 메모리를 절약할 수 있음
세그먼트(Segment)
: 메모리에서 일정 부분을 의미
- 일반적인 주소 공간은 4개의 세그먼트로 구성
-> Code, Data, Stack, Heap
- OS는 3개의 세그먼트를 메모리에 배치하여 Heap과 Stack 사이의 공간을 낭비하지 않도록 하는 것
2. 구현
- 가상 주소는 segment id + offset으로 구할 수 있음
- segment id는 상위 2개의 비트로 구분할 수 있음
- offset은 하위 12개의 비트로 계산할 수 있음
1) Heap
- EXAMPLE)
- Segment ID가 01인 Heap 영역에 가서 Base 값을 찾음 (Base = 26K)
- Offset을 계산 (16진수 Hex -> 10진수 Decimal) -> 0x68 = (16^1X6) + (16^0X8) = 104
- segmentation fault가 발생했는지 확인 -> Offset값과 Bound 값을 비교 -> Offset < Bound
- segmentation fault : 프로그램이 허용되지 않은 메모리 영역에 접근을 시도하거나, 허용되지 않은 방법으로 메모리 영역에 접근을 시도할 경우 발생
- Phycal memory 주소를 찾음 -> base + offset -> Segment ID가 01인 Heap 영역에서 Base값과 Offset 값을 더함 -> 26KB + 104
2) Stack
- Stack은 Code, Heap 부분과 다르게 거꾸로 확장되기 때문에 주소 변환을 다르게 해야 함
-> Code, Heap은 sign이 Positive인 반면에 Stack은 sign이 Negative
- Stack 세그먼트의 base 레지스터는 가장 높은 주소에서 시작
- Segment ID가 10인 Stack 영역에서 Base 값을 찾음 (Base = 36K)
- Offset을 계산 (16진수 Hex -> 10진수 Decimal) -> 0xA00 = (16^2X10) + (16^1X0) + (16^0X0) = 2560Segmentation
- fault가 발생하는지 확인 -> Offset값과 Bound 값을 비교 -> Offset < Bound
- physical memory 주소를 찾음 -> base - offset -> 36KB - 2560
3) Code Sharing
- 세그먼트는 추가적인 하드웨어 지원을 통해 주소 공간 사이에서 공유될 수 있음
- So, 다중 프로세스는 Code 세그먼트를 공유할 수 있는데, 읽고 실행은 가능하지만 값을 변경할 수는 없음
- 코드가 지정된 영역은 접근 가능하지만, 값을 바꿀 수는 없음
3. 문제
1) Context Switching에 대해서는 OS가 어떻게 처리하는가 ?
- 세그먼트 레지스터의 값들을 저장하고 복원해주는 방식으로 처리
2) 세그먼트의 수가 증가하거나 감소할 때 OS와 어떻게 상호작용하는가 ?
- 상황) Heap 공간이 부족해서 malloc()에 의해 Heap공간을 늘려야 하는 경우
- 해결 방안) 공간을 늘리기 위해 sbrk() system call을 사용 -> sbrk()는 힙을 늘리거나 줄이는 함수
3) physical memory에 여유 공간을 어떻게 관리할 것인가 ?
- 프로세스마다 크기가 모두 다르기 때문에 각 세그먼트의 크기도 모두 다름
-> 외부 단편화(external gragmentation) 문제 발생
- 외부 단편화 : 외부가 잘게 쪼개진 형태
- 상황) 왼쪽 메모리에서 20KB 크기를 갖는 세그먼트를 할당하려고 함, But, 전체로 보면 24KB 여유 공간이 있지만 16KB, 4KB, 4KB로 인접하지 않은 세그먼트로 20KB 크기를 갖는 공간을 할당받을 수 없음
- 해결 방안) OS는 가운데 그림처럼 Compaction이라는 방법으로 실제 메모리에 있는 기존의 세그먼트를 재배치함
-> 비용이 발생하여 성능이 떨어지는 문제점이 존재
- So, 오른 쪽의 그림처럼 페이징(Paging)이라는 기법을 통해 고정적인 크기의 세그먼트로 외부 단편화를 제거하여 여유 공간을 관리할 수 있음
- But, 페이징 기법 역시 내부 단편화 문제가 존재
- 내부 단편화 : 15KB 요청이 오면 8KB * 2번으로 16KB를 주게 되면 1KB의 안쓰는 공간이 생김 -> 1KB가 내부 단편화의 문제점
'운영체제' 카테고리의 다른 글
12. 가상 메모리 & 요구 페이징 & 페이지 교체 (0) | 2025.02.10 |
---|---|
11. 페이징(Paging) (0) | 2025.02.10 |
9. 주소 변환(Address Translation) (0) | 2025.01.23 |
8. 주소 공간과 가상 메모리(Address Space, Virtual Memory) (0) | 2025.01.23 |
7. Context Switching(문맥 교환) (0) | 2025.01.23 |