본문 바로가기
computer science/운영체제

[운영체제] 메모리 관리

by 박연호의 개발 블로그 2020. 4. 27.


logical address vs physical address

 

1. Logical address(= virtual address)

각 프로세스마다 독립적으로 가지는 주소공간으로 주소가 0부터 시작하여 CPU가 보는 주소는 logical address임

 

2. Physical adddress

물리 메모리에 실제 올라가는 위치

 

※ 주소 바인딩

각 프로세스마다 0번지부터 시작하는데 물리 메모리에 올리기 위해서는 주소가 바뀌게 되는데 이렇게 이렇게 logical address를 physical address로 바꾸는 과정을 거침


logical address는 physical address로 언제 바뀌는가 ?

 

1. Compile time binding

physical address가 컴파일 시 결정되며 시작 위치 변경 시 컴파일 과정을 다시 거침. 과거 시스템내에 하나의 프로그램을 실행할 때 사용되었으며 최근의 시스템에서는 사용하지 않음 

 

2. Load time binding

소스코드가 컴파일되어 logical address만 결정되고 메모리에 올라갈 때 physical address가 결정되며, loader의 책임하에 physical address를 부여하여 컴파일러가 재배치가능코드를 생성한 경우 가능

 

3. Execution time binding( =Run time binding)

Load time binding 처럼 physical address가 프로그램 실행시에 결정되며, 차이점은 수행이 시작된 이후에도 프로세스의 메모리 상 위치를 옮길 수 있음, cpu가 주소를 참조할 때마다 binding을 점검(address mapping table)하며 하드웨어적인 지원이 필요(base and limit register, MMU)

 

※ Compile time binding, Load time binding은 physical address가 고정되어 있지만 execution time binding은 실행시에 address가 계속 바뀔 수 있음


MMU(Memory Management Unit)

 

logical address를 physical address로 mapping해주는 hardware device로 사용자 프로세스가 cpu에서 수행되며 생성해내는 모든 주소값에 대해 base register(relocation register)의 값을 더합니다. 

 

virtual memory 상의 logical addres가 346이라고 할 때, relocation register값을 더한 값이 실제 physical address가 됩니다. 여기서 relocation register을 더하기 전에 logical address가 limit register보다 더 큰지 검사를 하는데 큰 경우라면 sw interrupt(trap)을 발생시킵니다. 


관련된 몇가지 용어

 

1. Dynamic Loading

프로세스 전체를 물리 메모리에 미리 다 올리는 것이 아니라 해당 루틴이 불려질 때 메모리에 load하는 방법으로 오류 처리 루틴처럼 가끔씩 사용되는 많의 양의 코드의 경우 필요할 때마다 물리 메모리에 올림. 운영체제의 특별한 지원 없이 프로그램 자체에서 구현가능 

 

2. Dynamic Linking

※ linking이란 여러군데에 존재하는 컴파일된 파일들을 묶어서 하나의 실행파일을 만드는 것, 이런 파일들은 내가 마든 것 일 수도있고 라이브러리일 수도 있음

 

- static linking

라이브러리가 프로그램의 실행 파일 코드에 포함됨

실행 파일의 크기가 커짐 동일한 라이브러리를 각각의 프로세스가 메모리에 올라가므로 메모리 낭비(ex, printf 함수의 라이브러리 코드)

 

- dynamic linking

라이브러리가 실행시 연결(link)됨

라이브러리 호출 부분에 라이브러리 루틴의 위치를 찾기 위핸 작은 코드를 둠

라이브러리가 이미 메모리에 있으면 그 루틴의 주소로 가고 없으면 디스크에서 읽어옴

운영체제의 도움이 필요

 

3. Overlays

메모리에 프로세스의 부분 중 실제로 필요한 정보만을 올리며 프로세스의 크기가 메모리 보다 클 때 유용, 운영체제의 지원 없이 사용자에 의해 구현되며 작은 공간의 메모리가 사용하던 초창기 시스템에서 수작업으로 프로그래머가 구현

 

4. Swapping

프로세스를 일시적으로 메모리에서 backing store(디스크의 일부영역)로 쫓아내는 것

일반적으로 중기 스케줄러에 의해 swap out 시킬 프로세스를 선정하며 우선순위가 낮은 프로세스를 swapped out시키고 우선순위가 높은 프로세스를 메모리에 올려 놓음. compile time 혹은 load time binding에서는 원래 메모리 위치로 swap in해야 하며 Execution time binding에서는 추후 빈 메모리 영역 아무 곳에나 올릴 수 있음


Allocation of Physical Memory

메모리는 일반적으로  두 영역으로 나누어 사용합니다

 

- OS 상주영역 : interrupt vector와 함께 낮은 주소 영역 사용

- 사용자 프로세스 영역 : 높은 주소 영역 사용

 

사용자 프로세스 영역의 할방 방법

1. contiguous allocation  각각의 프로세스가 메모리의 연속적인 공간에 적재되도록 하는 것

2. noncontiguous allocation : 하나의 프로세스가 메모리의 여러 영역에 분산되어 올라갈 수 있음


사용자 프로세스 영역의 할당 방법

메모리는 일반적으로  두 영역으로 나누어 사용합니다

- OS 상주영역 : interrupt vector와 함께 낮은 주소 영역 사용

- 사용자 프로세스 영역 : 높은 주소 영역 사용

 

1. contiguous allocation  각각의 프로세스가 메모리의 연속적인 공간에 적재되도록 하는 것

- 고정 분할 방식

물리적 메모리를 몇개의 영구적 분할(partition)으로 나눔

분할의 크기가 모두 동일한 방식과 서로 다른 방식이 존재

분할당 하나의 프로그램 적재

융통성이 없음 : 동시에 메모리에 load되는 프로그램 수가 고정, 최대 수행 가능 프로그램 수 또한 제한

internal fragmentation 발생(external gragmentation도 발생)

 

 

- 가변 분할 방식

프로그램의 크기를 고려해서 할당

분할의 크기, 개수가 동적으로 변함

기술적 관리 기법 필요

External fragmentation 발생

 

- Hole

물리 메모리상의 가용 메모리 공간

다양한 크기의 hole들이 메모리 여러 곳에 흩어져 있음

프로세스가 도착하면 수용가능한 hole을 할당

운영체제는 할당 공간, 가용 공간의 정보를 유지해야함

 

- Compaction

external fragmentation 문제를 해결하는 한가지 방법

사용 중인 메모리 영역을 한군데로 몰고 hole들을 다른 한 곳으로 몰아 큰 가용공간을 확보

매우 비용이 많이 드는 방법으로 최소한의 메모리 이동으로 compaction 하는 방법(매우 복잡)

compaction은 프로세스의 주소가 실행 시간에 동적으로 재배치 가능한 경우에만 수행 가능함

 

- 프로세스를 어느 hole에 넣어야 할까 ?

: Dynamic Storage Allocation Problem으로 size가 n인 요청을 만족하는 가장 적절한 hole을 찾는 문제

 

1. First - fit : size가 n 이상인 것 중 최초로 찾아지는 hole에 할당

2. Best - fit : size가 n 이상인 가장 작은 hole에 할당, hole들의 리스트 크기가 정렬되지 않은 경우 리스트를 탐색해야 함

3. Worst - fit : 가장 큰 hole에 할당, 모든 리스트를 탐색해야 함

 

→ First - fit과 Best - fit이 Worst - fit보다 속도와 공간 이용률 측면에서 효과적임

 

2. noncontiguous allocation : 하나의 프로세스가 메모리의 여러 영역에 분산되어 올라갈 수 있음

 - paging : process의 virtual memory를 동일한 page로 나누어 물리 메모리에 올림

- segmentation : process의 virtual memory를 segment단위(code, data...)로 물리 메모리에 올림

- paged segmentation : page와 segmentation을 혼용한 방법

 

※ 위의 방법은 아래에서 다시 자세히 다룸


Paging 기법

process의 virtual memory를 동일한 사이즈(보통 4K)의 page로 나어 page 단위로 물리 메모리에 불연속적으로 저장되며 일부는 backing store, 일부는 physical memory에 저장됩니다.

 

physical memory와 virtual memory를 동일한 크기로 나누고 각각 frame, page로 부릅니다. 또한 이들간의 관계는 page table을 사용하여 logical address를 physical addre로 변환하며 external fragmentation은 발생하지 않지만 internal fragmentation을 발생할 수 있습니다.

 

제일 위의 첫번째 사진을 다른 구조로 살펴보면 위의 사진과 같은 모습이 나옵니다.

cpu가보는 logical address는 physical address상의 주소로 변환되어야 하는데 이 변환과정에서 page table을 사용합니다. logical address에서 앞부분p는 페이지 번호, 뒷부분d는 페이지 내의 offset이 됩니다. page table에서는 페이지 번호를 사용하여 프레임 번호(f)를 찾아서 physical address를 구할 수 있습니다.  


TLB

page table은 물리 메모리에 상주합니다. 그리고 주소 매핑을 할 때 2가지의 register를 사용합니다.

 

- Page Table Base Register(PTBR) : relocation register 역할을 하며 page table을 가리킴

- Page Table Length Register(PTLR) :  limite register 역할을 하며 테이블 크기를 저장

 

page table에 의해 logical address를 physical address로 매핑을 하면 실제 물리 메모리의 주소에 접근하여 연산을 합니다. 이런 경우 ㅣ실제 데이터를 연산하는데 page table 접근 1번, 물리 메모리의 data/instruction 접근 1번 총 2번의 물리 메모리 접근을 하게 됩니다. 이런 경우 속도향상을 위해 메인 메모리와 cpu사이에 존재하는 TLB(translation look-aside buffer) 고속의 lookup hardware cache를 사용합니다.

 

기존의 경우 page table와 데이터가 물리 메모리에 있기 때문에 실제 물리 메모리의 데이터에 접근하기 위해서는 총 2번의 물리메모리 접근이 필요했습니다. 하지만 속도 향상을 위해 cpu와 물리 메모리 사이에 cache를 두어 page table에서 자주 참조되는 entry를 caching합니다.

 

그래서 logical address를 physical address를 변환하기 전에 물리 메모리의 page table을 보기 전에 먼저 TLB를 봅니다. 그래서 p에 대항하는 페이지 번호가 caching되어 있으면(TLB hit) 바로 주소변환을 해서 물리 메모리에 접근합니다. 그렇지 않은 경우(TLB miss) 일반적인 경우처럼 page table을 사용하여 주소변환 후 물리 메모리에 접근합니다.

 

 TLB에서 caching되어 있는 정보를 확인하기 위해 전체 리스트를 검색해야 하는 overhead가 발생합니다. 이런 문제를 해결하기 위해 TLB는 Associative Registers를 사용하여 병렬적으로 즉, cpu가 p정보를 주면 하나 하나 검사하지 않고 한번에 검색하게 됩니다.

 

page table은 각 프로세스마다 존재하므로 TLB 프로세스가 교체될 때마다(context switch) 모든 엔트리 정보를 제거해야 합니다. 


Valid / Invalid Bit in a Page Table

 

 

page table내는 해당 페이지가 물리 메모리(프레임)에 올라가 있는지를 확인할 수 있는 valid/invalid bit가 존재합니다. 

 

- protection bit

page의 연산에 대한 접근 권한(read/write/read-only)

code의 경우 read-only이지만 data,stack은 연산이 가능하므로 read/write권한을 부여

 

- valid

해당 주소의 frame에 그 프로세스를 구성하는 유효한 내용이 있음을 뜻함

 

- invalid

해당 주소의 frame에 유효한 내용이 없음을 뜻함, 2가지 경우로 나누어 생각할 수 있음

1) 프로세스가 그 주소 부분을 사용하지 않는 경우

2) 해당 페이지가 메모리에 올라와 있지 않고 swap area에 있는 경우  


Demand Paging

프로그램을 실행할 때 해당 프로스를 모두 물리 메모리에 올려놓고 실행하지 않습니다. 특정 단위로 프로세스를 쪼개서 당장 실행에 필요한 부분을 물리 메모리에 올려놓고 실행하죠. 이를  Demand Paging이라고 합니다. 이런 방법을 사용함으로써 필요한 것만 올리기 때문에 I/O 양이 감소, Memory 사용량 감소, 빠른 응답 시간, 더 많은 사용자 수용 등의 효과를 얻을 수 있습니다.

 

page table의 각 entry에는 valid/invalid가 있다고 했습니다. valid는 해당 페이지가 물리 메모리에 있는 경우 invalid는 해당 페이지가 물리 메모리에 없거나(backing store에 있는 경우) 사용되지 않은 주소 영역인 경우를 의미합니다.    

 

처음에는 모든 page entry가 invalid로 초기화되어 있습니다. 만약 A페이지를 cpu가 읽기 위해 page table을 참조하는데 만약 invalid인 경우 해당 페이지를 디스크(backing store)에서 읽어 와야합니다. 이런 상황을 page fault라고합니다.

 

 

해당 페이지를 참조하기 위해 page table을 보는데 invalid로 되어 있습니다. 즉, page fault가 발생하면 MMU가 trap을 발생시키고 CPU제어권이 운영체제에게 넘어가게 됩니다(실행중이던 프로세스의 context는 PCB에 저장됨). 운영체제는 디스크로 부터 페이지를 읽어와 프레임에 올리고(인터럽트 서비스 루틴) page table의 해당 페이지를 valid로 바꿉니다. 이후 원래 프로세스로 cpu를 넘겨주고 context 복구 후 기존에 진행하던 작업을 합니다(우선순위에 따라 다른 프로세스에게 cpu 제어권이 넘어갈 수 있음)


물리 메모리에서 어떤 페이지를 쫓아 내야할까 ?

1. Optimal Algorithm

Optimal Algorithm은 미래에 사용된 페이지에 대한 정보를 안다고 가정하여 가장 먼 미래에 사용되는 페이지를 교체하는 방법입니다.  어떤 알고리즘의 성능도 optimal algorithm보다 좋은 순 없는데 optimal algorithm 알고리즘은 실제 시스템에서는 사용하지 않으면 알고리즘의 성능을 판단하는 기준으로 사용합니다. 예를 들어 X라는 알고리즘을 만들었는데 그 성능이 optimal algorithm의 성능과 비슷하다면 굉장히 좋은 알고리즘 이라고 생각할 수 있습니다.

 

빨간색은 page fault, 분홍색은 page를 참조한 경우를 의미하며 page를 교체해야 할 때 가장 먼 미래에 참조되는 page를 repalce 해줍니다. 예를 들어 7번째 "5" page를 참조할 때 6번째 까지의 참조된 페이지들은 [1,2,3,4]입니다. 이 중에서 가장 먼 미래에 참조되는 페이지는 4가 되기 때문에 page 4를 쫓아냅니다.

 

2. FIFO(First In First Out) Algorithm

시스템에서 사용 가능한 알고리즘으로 먼저 들어온 것을 먼저 내쫓는 방법입니다. 하지만 FIFO 알고리즘은 FIFO Anomaly라는 특징을 가지는데 이는 시스템의 효율을 높이기 위해 page frame을 더 높이는데도 더 많은 page fault가 발생하는 경우가 생깁니다.

 

 

3. LRU(Lease Recently Used) Algorithm

실제로 메모리 관리에서 가장 많이 사용하는 알고리즘으로 가장 오래전에 사용한 페이지를 쫓아내는 방법입니다. FIFO와 차이점은 FIFO는 가장 먼저 들어온 페이지를 쫓아내지만 LRU는 가장 오래전에 사용한 페이지를 쫓아냅니다. 만약 가장 먼저 들어왔어도 최근에 또 사용했다면 교체대상이 되는 page가 LRU와 FIFO는 다르게 됩니다.

 

7번째 "5" page를 참조할 때 현재 시점에서 가장 오래전에 사용한 페이지를 쫓아냅니다. 3 page가 가장 오래 되었기 때문에 교체해줍니다.

FIFO는 가장 먼저 들어온 페이지를 쫓아내는데 "1" page의 경우 최근에 사용되었음에도 불구하고 교체대상이 됩니다.

 

4. LFU(Least Frequently Used) , MFU(Most Frequently Used)Algorithm

LFU(Least Frequently Used)는 적재되어 있는 동안 참조된 횟수를 누적하여 기록한 후 그 값으로 교체 대상을 선택하는 기법이며, LFU는 많이 참조된 페이지는 앞으로 참조될 확률이 높을 것이라는 판단에 근거하여 값이 가장 작은 페이지를 선택합니다. 

 

MFU(Most Frequently Used)는 많이 참조된 페이지는 충분히 참조가 이루어졌으므로 더 이상 참조되지 않을 것이란 판단에 근거하여 가장 값이 큰 페이지를 선택합니다. 

 

두 기법모두 편향된 시각에 근거함으로써 실제로 구현되는 경우는 매우 드뭅니다.


Paging System에서 LRU, LFU를 사용할 수 있을까 ?

좀 뚱단지 같은 소리지만 paging system에서 위에서 공부한 LRU, LFU를 사용할 수 있을까요 ? 정답은 없습니다...

 

LRU, LFU를 사용하기 위해서는 자료구조를 사용하여 page에 대한 관리가 필요합니다. 즉 페이지를 사용할 때 마다 자료구조상에서 그 위치를 바꿔줘여하고 마찬가지로 LFU역시 참조횟수를 누적해야 합니다.

 

이런 일은 cpu가 할 수 있을까요 ? cpu는 단지 pc의 값을 읽고 실행만하며 그 뿐입니다. 이런 일은 os가 해주어야 합니다. 만약 page가 물리 메모리에 있다면 LRU, LFU 알고리즘에 맞도록 자료구조 상에서 어떤 조작을 해야 합니다. 하지만 실제로 page가 물리 메모리에 있다면 OS는 전혀 일을 하지 않습니다. 단지 하드웨어 적으로 MMU가 logical address를 physical address로 바꿔주고 cpu를 그걸 읽을 뿐입니다.

 

결론적으로는 LRU, LFU 알고리즘을 사용하기 위해서는 page의 정보를 관리하는 자료구조가 필요한데 그러기 위해서는 os가 cpu를 얻어야 합니다. 메모리에 이미 있는 page에 대해서는 os에 cpu가 넘어오지 않기 때문에 LRU, LFU 알고리즘을 사용할 수 없습니다. 

 

위에서 설명을 하였지만 paging system에 사용할 수 있는 알고리즘은 아닙니다. 대신 buffer caching, web caching에서는 사용할 수있습니다.

 

....

 

clock algorithm

대신에 paging system에서는 일반적으로 clock algorithm을 사용합니다. LRU의 근사 알고리즘으로 NRU(Not Used Recently) 또는 NRU(Not Recently Used), Second Change Algorithm으로 불립니다.

 

clock algorithm에서는 page table의 각 entry에 존재하는 reference bit를 사용합니다. 어떤 페이지가 참조되어서 cpu가 그 페이지를 사용하게 되면 MMU는 물리 메모리로 변환해 주면서 해당 Page table 페이지 내의 reference bit를 1로 set합니다.

 

※ 여기서 h/w는 reference bit를  1로바꾸고 os는 hw가 1로 바꿔놓은 reference bit를 보고 1은 0으로 바꾸고 0인 page를 쫓아냅니다.

 

만약 page fault가 나서 어떤 page를 쫓아내야 하는 경우 reference bit를 참조합니다. 만약 reference bit가 1이라면 해당 page가 적어도 한번은 참조되었구나 라 생각하고 0(참조되는 page이므로 한번 기회를 줍니다)으로 바꿔놓습니다. 그리고 그 다음 page를 검사하다가 만약 reference bit가 0이라면 해당 page 내쫓습니다. 

 

다시 생각해보면 reference bit가 1인 경우는 시계바늘이 움직이는 동안 해당 페이지가 참조되었음을 의미합니다. 반대로 다시 생각해보면 reference bit가 0은 시계바늘이 한바퀴를 도는 동안 해당 page의 참조가 없었다는 것을 의미합니다. 그렇기 때문에 시계바늘이 움직이다 reference bit가 0인 page를 내쫓습니다(최근에 사용되지 않았기 때문이죠)

 

 

개선된 clock algorithm

만약 page를 교체할 때 단순히 cpu가 page를 read한 경우 말고도 page의 내용을 수정하는 write작업을 했을 수도 있습니다. 이런 경우 해당 page 그냥 지우는 것이 아니라 backing store에 수정된 내용은 반영하고 지워야 합니다. 이렇게 해당 page table의 각 entry에는 페이지가 최근에 변경되었는지를 확인할 수 있는 modified bit(dirty bit)가 존재합니다.

 

따라서 clock algorithm를 사용하여 교체할 페이지를 선택했는데 modified bit가 1인 경우 추가적인 overhead가 발생하기 때문에 modified bit가 1인 페이지보다 0인 페이지를 선택하는것이 더 빠른 속도를 보장할 수 있습니다.


각 프로세스당 얼마만큼의 page frame을 할당할 것인가 ?

프로세스 각각 명령어 수행을 위해 최소한으로 할당되어야 하는 frame수가 존재합니다. 만약 loop문에서 최소한의 allocation이 없으면 매 loop마다 page fault가 발생할 수 있고, 특정 프로세스가 대부분의 frame을 잡아먹어 버리는 일이 발생할 수도 있습니다.

 

여기서 page frame을 할당할 수 있는 방법에는 2 가지가 있습니다.

 

1. Global Remplacement

각 프로세스에게 미리 page를 할당하지 않고 FIFO, LRU, LFU등의 알고리즘을 사용하여 frame를 많이 필요로 하는 프로세스에게는 많이 주며 유동적으로 frame을 프로세스에게 할당합니다. 또한 Working set, PFF알고리즘을 각 프로세스에게 어느정도의 frame을 할당합니다.

 

2. Local Remplacement

자신에게 할당된 frame 내에서만 교체하며 FIFO, LRU, LFU 등의 알고리즘을 프로세스 별로 운영합니다.


Trashing

프로세스의 원활한 수행에 필요한 최소한의 page frame 수를 할당받지 못하는 경우 발생하여 지나치게 page fault가 많이 발생하는 현상. 이며 다음과 같은 특징을 가집니다.

 

- cpu 이용률 저하

- os는 MPD(Multiprogramming degree)를 높여야 한다고 판단

- 또다른 프로세스가 시스템에 추가됨(higher MPD)

- 프로세스당 할당된 frame의 수가 더욱 감소

- 프로세스는 page의 swap in/out으로 매우 바쁨

- 대부분의 시간에 cpu는 한가함

- low throughput

 

x축은 프로세스의 수, y축은 cpu 이용률 입니다. 일반적으로 Multiprogramming degree의 수를 높이면 cpu의 이용률이 높아져 전체적인 시스템의 성능이 좋아집니다. 하지만 계속해서 Multiprogramming degree를 높이다 보면 cpu이용률이 갑자기 낮아지는 구간이 발생하는데 이를 trashing이라고 합니다.

 

이런 현상이 발생하는 이유는 프로세스가 많아 짐에따라 각 프로세스에 할당된 frame수가 적어지기 때문입니다. cpu는 이 상황을 보고 cpu이용률이 낮다고 판단하며 MPD(Multiprogramming degree)를 높여야 한다고 생각합니다. 그래서 또 다른 프로세스를 프로세스에 추가하는데 이는 프로세스 당 할당된 frame의 수가 더욱 감소하게 됩니다. 때문에 프로세스는 page의 swap in/out으로 매우 바쁘며 대부분의 시간에 cpu를 일을 하지 않게 됩니다. 

 

이를 해결하는 방법은 Multiprogramming degree를 잘 조절해주어야 합니다. 이런 역할을 해주는것이 방법이 Working set model, PFF(Page Fault Frequency)입니다.


Working Set Model

 

프로세스는 특정 시간 동안 일정 장소만을 집중적으로 참조하여 이렇게 집중적으로 참조되는 해당 page들의 집합을 locality set이라고 하며 working set model에서는 이런 locality set을 working set이라고 합니다.

 

Multiprogramming degree가 너무 높아져 trashing이 발생하면 각 프로세스마다의 working set을 보장할 수 없습니다. 시스템 내에 프로세스가 많아짐에 따라 프로세스 당 frame의 수는 낮아지니깐요. 

 

이런 상황에서 working set 모델에서는 프로세스의 working set 전체가 메모리에 올라와 있어야 수행되고 그렇지 않을 경우 frame을 반납 후 swap out(suspend)합니다. 내가 frame이 5개가 필요한데 3개밖에 못준다고 하면 그냥 디스크로 내려가 있는 것입니다. 이런 경우 trashing을 방지할 수 있으며 Multiprogramming degree를 조절할 수 있습니다.


PFF(Page Fault Frequency)

 

PFF 현재 시스템, 특정 프로세스가 page fault을 얼마나 내는지 보고 page fault가 상한 기준점이상 이면 frame을 더 할당하고 하한 기준 이하이면 frame수를 할당합니다. 하지만 빈 frame이 없으면 일부 프로세스를 swap out 합니다. 

 


Segmentation 기법

프로그램을 의미 단위인 여러개의 segment로 나누는 방법으로 작게는 함수 하나하나를, 크게는 프로그램 전체를 하나의 세그먼트로 정의하며 일반적으로는 code, data, stack부분이 하나씩의 세그먼트로 정의됩니다.

 

segment는 다음과 같은 logical unit이 됩니다.

- main()

- function

- global varialbes

- symbal table, arrays

 

logical address는 <segment-number, offset>으로 구성됩니다.

 

- segment table은 다음 2가지를 가집니다.

base : 세그먼트의 시작 물리주소

limit : 세그먼트의 길이(paging기법의 경우 크기가 모두 같지만 segment기법의 경우 segment의 길이가 모두 다르기 때문에)

 

- Segment Table Base Register(STBR) : 물리적 메모리에서의 segment table의 위치

- Segment Table Length Register(STLR) : 프로그램이 사용하는 segment의 수  

 

cpu가 논리 주소를 주게되면 세그먼트 번호(s)와 오프셋(d)로 나눕니다. 세그먼트 시작 위치는 register에 저장되어 있으며 거기서 부터 세그먼트 번호만큼 떨어진 위치에 가면 해당 세그먼트가 물리적 메모리의 어떤 번지에 올라가 있는지 알 수 있습니다.

 

segment table에서는 주소를 변환하기 전에 다음과 같은 작업을 합니다.

- 세그먼트 번호(s)가 STLR(프로그램의 segment의 수)보다 큰지를 검사하고 큰 경우 trap을 발생시킵니다

- 세그먼트의 길이보다 오프셋(d)가 더 큰지를 검사하고 큰 경우 trap을 발생시킵니다.

 

프로세스의 주소 공간은 여러 segment로 나누고 실제로 물리 메모리에 올릴 때에는 segment table을 참조하여 각각의 segment를 물리 메모리에 올립니다. segment는 의미 단위이기 때문에 공유와 보안에 있어 paging보다 훨씬 효과적이며 segment의 길이가 동일하지 않으므로 external fragmentation이 발생합니다.