OS - 메모리 관리

Logical Address & Physical Address

물리적인 메모리에는 아래에는 운영체제, 위에는 프로세스들이 올라가게 된다.

os_10_1

물론 프로세스들은 바로 Physical Address(물리적 메모리)를 통해 데이터 접근을 하지 않고 Logical Address(가상 메모리)를 통해 데이터에 접근한다.

Logical Address 에서 Physical Address 로 접근할 때는 주소 변환 과정이 필요하다.

우리가 프로그래밍 할 때 변수나 함수 이름을 사용해서 개발하지 변수와 함수의 주소를 사용해서 개발하진 않는다.
이렇게 이름을 사용해 접근할 때 사용하는 것을 Symbolic Address 라 한다.

컴파일이 돼서 실행파일이 만들어지게 되면 프로그램만의 독자적인 메모리 주소 Logical Address 가 만들어 지고

실제 컴퓨터에서 실행되는 것은 Physical Address 에서 실행된다.

Address Binding

CPU 가 프로그램 실행시 Physical Address 를 볼 것 같지만 Logical Address 를 바라본다.

os_10_2

그림을 보면 컴파일 돼서 만들어진 프로그램이 실행되고
Physical Address 에 프로세스의 코드가 올라간 걸 보면 Logical Address 에서 사용하던 주소 값을 그대로 사용 중이다.

최종적으로 데이터에 접근하기 위해 Logical AddressPhysical Address 변환시키기 위해 Address Binding 작업을 거쳐야 한다.

Address Binding 은 하드웨어의 도움을 통해 이루어진다

그림처럼 Address Binding 은 3가지

  • Compile time binding
  • Load time binding
  • Rum time binding

Compile time binding

Physical Address 가 컴파일 시 정해지는 구조

옛날에 컴퓨터에서 프로그램 한 개만 실행되던 시절 사용하는 방법이다.

현대 범용 시스템에선 가장 아랫단에 OS가 올라가기 때문에 프로세스는 0부터 사용할 수 없다.
이렇게 컴파일러가 생성한 코드를 Absolute code(절대코드)라 한다.

Load time binding

프로그램이 실행 시 Physical Address가 결정되는 구조.

프로세스가 사용하는 물리적 시작 주소 위치는 랜덤하게 결정된다.
이 구조에서 컴파일러가 생성한 코드를 Relocation code(재배치가능코드)라 한다.

Rum time binding

Execution time binding 이라고도 함

Load time binding 과 마찬가지로 실행 시 Physical Address 가 결정되는 구조.

차이점은 Load time binding 은 한번 실행되면 물리 주소 위치를 바꿀 수 없지만
Run time binding 은 실행 도중에 위치를 옮길 수 있다.

실행 중 Physical Address 가 언제 어디로 바뀔지 모르기 때문에
Logical Address와 만날 때 마다 Address Mapping table 을 사용해 Address Binding 이 잘 돼있는지 점검해야한다.

Address Mapping table + Address Binding 은 하드웨어로 빠르게 처리하는것이 필요하다.

Memory Management Unit (MMU)

위에서 말한 Address Binding 을 지원하는 하드웨어.

os_10_3

프로세스 Virtual Memory 는 통짜 그대로 올라가는 것이 아니고 쪼개져서 산발적으로 올라간다.

하지만 지금은 그림처럼 그대로 올라간다고 가정해보자

그대로 올라가는 방식을 연속할당 방식이라함

CPU가 346번지(Logical Address)의 data를 요청,
MMU 는 해당 프로세스 데이터가 14000번지(Physical Address) 부터 올라가있기 때문에 그만큼 더해서 변환한다.

물리메모리에 프로세스가 통째로 올라간다는 가정 하에 MMU에 레지스터 2개만 있으면 해결가능하다.

  • Relocation register: 접근할 프로세스 메모리 시작위치(최소값)를 갖고 있는 레지스터, base register 라고도 함
  • Limit register: 메모리 범위를 결정하는 레지스터

굳이 Limit register 를 두는 이유는 프로세스가 악의적으로 본인의 주소공간이 아닌 다른 프로세스의 주소공간을 요청할 수 있기 때문이다.

os_10_4

요청한 주소가 Limit register 보다 작다면 정상적으로 진행시키고 아니라면 trap(소프트웨어 인터럽트)를 발생시킨다.

정상적으로 진행된다면 Relocation register 만큼 더해 메모리에 접근하게된다.

즉 CPU도 소프트웨어도 논리적인 주소만 보고 물리적 주소는 볼 수도 없고 알 필요도 없다.
실행되어 메모리에 접근할 때 MMU 에 의해서 물리메모리에 접근하게 된다.

프로세스가 메모리에 올라가는 여러 방식들

Dynamic Loading(동적 연결)

프로세스 전체를 메모리에 미리 다 올리지 않고 해당 루틴이 불릴 때마다 메모리에 Load하는 것.
memory utilization(활용률)이 향상된다.

좋은 프로그램들은 예외상황을 처리하는 오류처리 코드들이 많은데 이런 코드들은 평상시 사용되지 않는다.
이런 코드까지 메모리에 올리면 비효율적이기 때문에 Dynamic Loading 을 사용해야 한다.

Dynamic Loading은 옛날에 만들어진 용어로 원래 OS지원 없이 프로그램 자체 에서 해당기능이 구현 됐을 때 생긴 용어다.

현재는 OS가 이와 같은 기능을 라이브러리를 통해 지원한다 (Dynamic loading 기술이라 봐도 무방함).

Overlays(중첩)

메모리에 프로세스의 부분 중 실제 필요한 부분만 올리는 기술로 Dynamic Loading 이랑 같은 개념이지만 더 옛날 기술이다.

아주 작은 공간의 메모리를 사용하던 시절 프로그램이 메모리보다 클 때 상주부분과 그렇지 않은 Overlays 영역으로 구분하여 사용했던 기술이다.

수작업으로 프로그래머가 Overlays 구조를 설계해야 했다.

Swapping

os_10_5

오리지널 개념은 프로세스 통째를 일시적으로 메모리에서 쫓아내는 것을 의미한다.
주로 Disk같은 보조기억장치로 쫓아낸다.

쫓겨난 메모리 공간을 swap area(Backing store)라 한다.

쫒겨날 때가 Swap out
메모리로 돌아올 때가 swap in

CPU 중기 스케줄러에 대해 배웠었다(프로세스1 참고).
너무 많은 프로세스들이 메모리에 올라가 있으면 메모리가 부족하기에 일부 프로세스를 골라 통째로 쫓아내는데
CPU 우선순위가 낮은(당장 CPU 사용 가능성이 적은)프로세스를 기준으로 먼저 처리한다.

Swapping 기능을 효율적으로 사용하려면 Rum time binding 을 사용해야한다.

Compile time bindingLoad time binding 은 프로그램이 종료될 때까지 같은 물리 주소가 유지돼야하기 때문에 Swapping 에 제한이 있다
(쫓겨나고 돌아올 때 그 공간에 다른 프로세스가 있을 수 있음)

os_10_6

디스크에 접근(I/O요청)할 때 가장 많은 시간이 걸리는 부분은 Access Time(디스크 헤드가 움직이는 시간)이다.

헤드가 움직인 후 실제 데이터를 읽고 쓰는 시간은 굉장히 짧다.

이례적으로 Swapping 과정에서는 헤드가 움직이는 시간보다 데이터를 읽고 쓰는 시간이 더 많다
Swapping 은 메모리에서 프로세스를 통째로 쫓아내고 불러오는 과정이기 때문에 File I/O 랑 비교했을 때 훨씬 양이 많다.

현대 OS는 통째로 쫓아내는 경우도 물론 있지만 당장 사용하는 일부분만 올리고 일부분만 쫓아내는 Paging 기법을 주로 사용한다

Linking

프로그램에 내가 만든 코드도 포함되겠지만 남이 만들어놓은 라이브러리들도 들어간다.

즉 자신의 코드와 라이브러리가 연결돼야 하는데 이 작업을 Linking이라 한다.
프로그램은 컴파일이 되고 각종 라이브러리들이랑 Linking이 되어 실행파일로 만들어진다.

Static Linking (Static Library)

라이브러리가 내 만든 프로그램 실행파일 코드에 이미 포함돼있는 형태.
여러 라이브러리를 포함할수록 실행파일 크기가 커진다.

동일한 라이브러리들이 각 프로세스마다 포함돼 있으면 메모리 낭비.

Dynamic Linking (Shared Library)

라이브러리가 내 실행파일에 포함되지 않고 별도의 라이브러리 파일(Shared Library)로 존재, 라이브러리 함수 호출시 파일을 찾아서 메모리에 올린 후 연결하여 실행하는 방식이다.

찾기 위한 위치정보 코드(stub 이라 함)만 실행파일 안에 포함돼있는 형태이다.

라이브러리 파일을 공유하기 때문에 프로그램들이 라이브러리 함수가 필요할 때 마다 호출하여
같은 라이브러리 파일을 계속 메모리에 올리는 것이 아닌 한번만 하나만 올리고 사용하면 된다.

Linux에서 Shared Libraryso(Shared Object) 로 존재하고,
Windows 에선 dll(dynamic-link library) 파일로 존재한다.

라이브러리가 이미 메모리에 있으면 그 라이브러리 파일의 호출한 루틴의 주소로 가고 없으면 디스크에서 읽어 올린다.

Allocation Of Physical Memory(물리 메모리 관리)

보통 낮은 주소영역에는 OS가 그 위에는 사용자 프로세스들이 사용한다.

이 사용자 프로세스 메모리 영역을 관리하는 연속할당불연속할당 방법을 알아보자.

연속할당은 별거 없지만 불연속 할당은 매우매우 알게 많다….

Hole

연속, 불연속 할당을 알아보기 전에 Hole이란 용어를 알아야 한다.

os_10_7

회색은 가용메모리(비어있어 사용할 수 있는 공간)이고 Hole이라 한다.
연속할당 방법으로 프로그램을 실행하다보면 가용메모리 공간이 군데군데로 흩어지게 될 것이다.

나중엔 가용메모리 용량은 충분하지만 흩어져 있어 정작 프로세스를 실행하지 못하는 상태가 생길 수 있다.

Contiguous Allocation (연속할당)

프로그램이 쪼개지지 않고 통째로 메모리에 올라가는 방법.
주소변환이 간단하다.

연속할당은 두 가지로 나뉘는데 둘다 현대OS에는 사용되지 않는 방법들이다.

os_10_8

고정 분할 방식

Fixed Partition 이라고 하며 물리적 메모리를 여러 개 파티션으로 미리 나누어 놓은 형태

프로그램 크기에 맞게 파티션 안에 할당하는 방식이다.
고정 분할 방식에선 내부조각과 외부조각들이 생긴다.

프로그램B 가 분할3보다 작기 때문에 분할3 내부 남는 공간이 내부 조각이 생긴다.
프로그램B 입장에서 분할2역시 사용 못하는 남는 공간이기 때문에 외부 조각으로 본다.

낭비되는 Hole 공간이 생기는 비효율적 방법이다.

가변 분할 방식

Variable Partition 이라고 하며 메모리를 굳이 파티션으로 나누지 않고 사용하는 형태

가변분할 또한 그림처럼 프로그램이 종료되면 남는 공간인 외부 조각만 생긴다.

내부를 칭할 파티션이 없어져서 내부조각은 생기지 않는다.

가변분할 방식에서 크기n 인 프로세스에 가장 적적한 Hole 을 찾는 방법이 3가지 있다.

  1. First Fit
    크기가 n보다 큰 것 중 최초로 찾아지는 Hole에 할당.
    장점은 빨리 결정하니 빠르다.
  2. Best Fit
    크기에 딱 맞거나 큰 것 중에선 제일 작은 Hole에 할당.
    장점은 메모리 효율, 단점은 탐색해야하니 느리고 오히려 생겨나는 아주 작은 작은 조각들.
  3. Worst Fit 제일 큰 Hole에 할당. 이름부터 단점. 쓰면 안 됨.

당연히 프로세스 크기보다 Hole크기가 커야한다.

이런 작은 조각들을 외부 단편화(External Fragmentation)라 부르며
외부 단편화를 최소화 하기 위해 사용 중인 메모리 영역을 한군데로 몰고 Hole 들을 다른 한곳으로 몰아 큰 Hole 을 만들어야 한다.

Compaction(압축)기법 이라한다.

매우 비용이 많이 들고 프로그램들도 동적으로 메모리 주소가 바뀌어도 정상 실행 가능토록 해야 한다
(Run time binding만 가능).

Noncontiguous Allocation (불연속 할당)

프로세스의 Virtual Memory 가 여러 개로 잘려서 물리 메모리의 다른 위치에 올라간다.

불연속할당은 연속할당의 물리메모리 관리처럼 레지스터 2개로만 관리 할 수 없다.
그렇다고 비싼 레지스터를 막 쓸 순 없으니 Paging 기법을 사용해 관리한다.

Paging

불연속 할당의 대표적인 방법

프로세스의 메모리 공간을 동일한 사이즈의 page 로 나눈다.

32bit OS기준 보통 4KB로 나뉜다.
참고로 불연속 할당에선 외부조각이 발생하지 않고 내부조각만 발생한다
(모든 프로세스가 4KB로 딱 떨어지지 않고 생기는 자투리 때문에).

물리메모리에 page 를 올리기 위해 물리메모리를 page와 동일한 크기로 나누고 이를 frame이라 한다

page size=frame size.

당장 필요한 page 는 물리메모리에, 그렇지 않은 pageswap area 에 저장해 놓는다.

Page Table

32bit OS는 2^32 인 4GB만큼 메모리를 인식한다.
즉 프로그램이 최대로 사용할 수 있는 메모리 또한 4GB이다.

이를 페이지단위인 4KB로 자르면 100만개정도 된다.
레지스터를 100만개 쓸 순 없으니 page 들은 관리할 page table 을 사용해야한다.

각 프로세스별로 page table 을 사용해서 프로세스 Virtual Memory 에서 물리메모리에 접근하는 그림이다.

os_10_9

연속할당에선 Logical AddressPhysical Address간의 주소변환을 레지스터로 했다면 여기선 page table을 사용하여 변환한다.

page는 배열 형태로 배열의 entry 를 가지고 있고 크기는 4byte이다.

page table 상자밖의 숫자가 entry, 상자안의 숫자가 frame number.
여기서 entry=index

위 그림에는 프로세스의 모든 page 가 물리메모리에 올라가있지만 그렇지 않을 수도 있다
swap area 에 올라가있거나 아예 해당 페이지를 사용하지 않을 수 도 있다.

모든 page가 메모리에 올라가 있지 않은 그림이다.

os_10_10

올라가지 못한 pagepage table 안의 frame number=0 되고
그림처럼 entry 마다 Valid-Invalid bit 로 별도 표시한다.

그림엔 없지만 write, read 접근권한을 표시하는 protection bitentry 마다 있다.

page table 을 사용한 Address Binding

os_10_11

  • p: page 번호(entry)
  • f: frame 번호
  • d: offset

offsetframe 의 상대적 주소위치를 표시한다

page 에서 d 만큼 아래위치한 데이터에 접근하고 싶을 때
f 에서 d 만큼 아래위치한 데이터에 접근하면 된다.

CPU 연산시 pdRelocation registerLimit Register 에 저장하고
page table 은 물리메모리에 저장하면 된다.

그리고 CPU가 page table 을 접근, 관리하기 위한 레지스터 2개가 있다

  • page table base register(PTBR): page table 위치를 가리키는 레지스터
  • page table length register(PLTR): table크기를 보관하는 레지스터

그림에는 page table 이 물리메모리 밖에 있는 것처럼 보이지만 안에 있다.
page tableentry 개수는 100만개정도 되는데 물리메모리에 상주한다.

page table 이 메모리에 있기 때문에 프로세스 virtual memory 에 있는 데이터를 실제로 접근하려면 물리메모리에 총 2번 접근해야 한다.
page table접근할 때 1번, 주소변환 거치고 데이터 접근할 때 1번.

물리 메모리 접근은 속도 저하로 이어진다(레지스터가 메모리위치 주면 MMU거쳐서 변환작업 + 레지스터와 메모리와의 속도차이는 비교 불가).

Translation look aside buffer(TLB)

TLBAddress Binding 속도향상을 위해 주소변환 전담 캐시메모리 이다.
캐시메모리이다 보니 물리메모리에 상주하는 page table 접근하는 것 보다 빠르다.

os_10_12

먼저 TLB 에서 page - frame 매칭 되는 row 를 확인하고 없다면 어쩔 수 없이 page table을 사용한다.

컴퓨터에서 자주 접근하는 메모리는 정해져 있기에 TBL miss 발생확률은 생각보다 낮다.
메모리 접근 시간이 매우 매우 단축됨으로 반드시 있어야하는 레지스터.

TLB 는 index 가 순차적으로 있는 게 아니다(자료구조도 다름)

90page 에 해당하는 물리메모리의 frame 에 접근하고 싶다면 page table 은 배열 형태로 돼있기 때문에
90 X 4KB 위치 entry 로 가서 바로 frame 읽으면 된다.

따라서 전부 search 를 해야 하는데 이러면 오버헤드가 크기 때문에 associative register 라는 병렬 search 가 되는 하드웨어를 사용해야한다
(그림 보면 TLB옆 화살표가 여러개).

프로세스가 여러개이지만 TLB 는 1개뿐이다.
따라서 CPU가 문맥교환으로 인해 실행하는 프로세스가 바뀐다면 TLB안의 값을 전부 flush 하고 다시 채워 넣어야 한다.

컴퓨터 속도로 문맥교환의 불편함을 못느끼지만 내부적으로는 수많은 오버헤드가 발생중이다.

TLB를 통한 메모리 접근 시간이 어떻게 되는지 알아보자.

os_10_13

  1. TLB 접근시간 = ε.
  2. 메모리 접근시간 = 1.
  3. Hit radtio - TLB에 의해 주소변환이 이루어지는 비율 = α
  4. TLB miss는 1-a

참고로 TLB에 의해 메모리 접근하는 비율 Hit ratio 는 거의 1에 가깝다.

Two Level Page table (2단계 page table)

4GB Virtual Memortypage table 크기는 대략 4MB(4BYTE*100만) 정도 된다.
즉 프로세스 당 4MB 공간이 필요한데 4GB 물리메모리 입장에선 4MB메모리 할당이 부담된다.

2단계뿐 아니라 N단계 page table 을 사용할 수 도 있다.

os_10_14

그림을 보면 outer page table, 안쪽 page of page table 을 거쳐 메모리에 접근하는 것을 알 수 있다.
page table 이 하나였을 때도 메모리를 2번 접근하는 손해가 있었는데 2단계가 되면서 3번 접근하게 됐다.
속도는 손해지만 공간은 이득이다.

그림만 보면 속도도 공간도 2배 손해인 것처럼 보이지만 아니다.
어떻게 메모리 공간을 아끼는지 알아보자.

프로세스가 사용할 수 있는 주소공간이 4GB 라고 메모리에 4GB 만큼 차지하지 않는다.
이유는 프로세스는 stack, code, data로 구성되고 이를 100만개 page로 나누어 물리메모리에 필요한 부분만 올린다.

여기서 필요 없는 공간은 codestack사이에 비어있는 공간이다.
이 공간이 매우 큰데 이 부분은 물리메모리에 올라갈 일이 없다..

즉 100만개 page중 일부만 물리메모리에 올리고 나머지는 swap area 에 저장된다.
쓰지도 않는 부분을 위해 page tableentry 를 사용하면 낭비가 심하다.

page table도 100만개 entry 를 다올리지 말고 필요한 entry 들만 올리면 되지 않을까?
page tablepage 화 시켜 공간을 절약하는 것이다.

outer page table 안에 사용되지 않는 page 의 정보는 null 로 설정하면 page of page table 이 생성되지 않는다.

생성된 page of page table 은 4MB였던 크기는 4KB로 쪼개져 page화 되어 물리메모리안에 들어간다.
쪼개진 4KB 를 4BYTE 로 나누면 생성되는 frame 수는 1024 개다.

즉 쪼개진 page of page table 하나가 1024 개의 frame, 4KB*1024=4MB 물리메모리를 커버할 수 있다.

32bit 주소를 표현하기 위한 가장 작은 값이 4BYTE

예를들어 26MB 크기 프로세스가 메모리에 올라갈 때

outer page table 4KB, page of page table 4KB*7(28MB), 총 32KB만 있어도 페이징이 가능하다,

Two Level Page table 의 address bindging

2단계에선 주소변환 과정이 3부분으로 나누어진다.

os_10_15

  • d: 4KB를 BYTE단위로 표시위한 2의 12승인 12bit 4KB중 어딘가 접근해야하기 때문에
  • p1, p2: 각각 바깥쪽 안쪽 페이지 테이블의 순번(entry) 크기는 4KB를 4BYTE로 나눈 1K개를 표시위한 2의 10승인 10bit이다.

os_10_16

다단계로 갈수록 메모리절약이 가능하다.
대신 메모리를 다번 접근해야 하지만 TLB 로 커버가능하다.

TLB의 Hit ratio 가 높기 때문에 N단계 Paging 기법도 나쁘지 않다.

지금까지 Logical Address에서 Physical Address로 변환되는 과정을 배웠는데
여기서 OS가 하는 역할은 하나도 없다, MMU 와 같은 하드웨어가 진행한다.

Inverted page table (역방향 페이지 테이블)

물리 메모리를 그대로 page table로 본뜨는 방법
물리적 메모리 frameentry의 위치가 동기화 되어있다,

os_10_17

page table 도 프로세스별이 아닌 frame 과 동기화된 프로세스들이 같이 쓰는 page table 하나만 있으면 된다.

P1 Logical Addressppage 를 물리메모리에서 찾기 위해 page table 에서 수색하고
찾은 fentry 에서 찾았다면 같은 위치인 fframe 으로 가면된다.

page table 을 순차적으로 다 뒤져야 되기 때문에 오버헤드가 크다.

Logical Address에서 Physical Address로 변환하는 과정에선 효율이 나쁜대신
Physical Address를 사용해 Logical Address를 찾아가는 것이 더 간편한 구조로 이루어져있다.

위에선 말한 associative register 같이 병렬처리가 가능한 하드웨어로 page table 을 구성한다면 시간도 아끼고 공간도 아낄 수 있겠지만 큰 레지스터가 필요함으로 비싼 방식이다.

Shared Page

동일한 프로그램이으로 여러개 프로세스를 실행하면 code는 똑같고 data만 다르다.

동일한 code 를 여러개 물리메모리에 올리면 낭비니까
공유해서 쓰자는 개념이 Shared Code 이다

Re entry code또는 Pure Code라고도 한다.
동일한 프로그램이라 하더라도 각 프로세스의 datacode도 개별적으로 필요할 수 있는 부분을 private code & data 라고 한다.

os_10_18

그림을 보면 프로세스가 page 크기로 잘려있고 각각 page table을 갖고 있다.
그리고 우측 물리메모리 frame 에 일부가 올라가 있다.

그런데 각 프로세스의 1~3 page 를 보면 모두 3,4,6frame에 올라가있다.
이렇게 된 이유는 3개 다 동일한 프로그램이기 때문이다.

전에 IPC(프로세스 간 통신)개념에서 Shared Memory와는 다른 개념이다.
Shared Memory는 통신개념으로 프로세스간 읽고 쓰기가 가능했지만 Shared Code는 읽기만 가능하다.

Segmentation

paging 기법에선 동일 크기로 프로세스 Logical Address를 잘랐다면
Segmentation 은 의미를 기준으로 자르고 이를 segment 라 한다.

일반적으로 크게 code, data, stack 영역을 잘라 3개의 segment 로 만들 수 있고
또는 작게 code 영역을 main, function, 전역변수, 배열, symbol tablelogical unit 로 자를 수 있다.

segmentationsegment table이 있고 앞에는 segment번호, 뒤에는 offset으로 구성된다.

os_10_19

  • s: segment 번호
  • d: offset

segment table 에서 segment 찾아서 물리메모리 시작위치인 base를 찾아 d 만큼 떨어진 위치로 접근한다.
segment 길이가 재각각이기 때문에 정확한 위치를 표시하기 위해 base 에는 BYTE 단위 주소가 들어간다.

base 외에 limit도 있는데 segment 의 크기가 제각각이기 때문에 잘못된(불순한) 위치접근을 막기 위해 별도로 크기정보를 가지고 있다.

segmentation 기법도 레지스터가 필요하다.

paging 에선 limit register, relocation registerPTBRPTLR로 썼는데
segmentation 또한 segment table 위치와 segment의 수 를 저장하는 STBR, STLR를 사용한다.

만약 segment 번호 sSTLR register 에 저장된 값보다 크다면 잘못된(불순한) 접근이다.

Logical Addresssegment 로 나눠져 Physical Address 로 어떻게 들어가는 그림을 통해 알아보자.

os_10_20

  • limit: segment 의 길이
  • base: 시작위치

segmentation 기법의 장점은 의미단위로 나누기 때문에 의미 단위로 하는 일들은 쉽게 처리가능하다.
공유와 보안 같은 것들을 예로 들 수 있다.
code segment 를 공유시키고 ode, stack 은 함부로 변경 못하도록 보안처리한다(read, write권한지정)
의미단위로 쪼개진 segment 를 통째로 처리하면 되니까 수월하다.

단점은 역시 가변크기다 보니까 Hole 이 생기는 것이다. paging 처럼 잘게 잘리는 것이 아니기 때문에 segment 가 물리메모리 해제되면 Hole 이 발생하는 단점이 있다.
아래 Segmentation With Paging 기법을 사용하면 해결가능하다.

물론 권한지정은 paging기법에서도 page 별로 권한을지정할 수 있기는 한다.

Shared segment

Shared Page와 유사하다.
segment 를 공유하려면 Logical Address에서 나눠진 segment 번호는 같아야한다.

os_10_21

segment table 크기도 작고 메모리도 더 아낄 수 있고 table이 작기 때문에 통째로 cache에 올리면 속도도 빠르겠지만
실제 segmentation 기법은 현대OS에서 거의 사용되지 않는다.

대부분 paging 기법을 사용한다.
사용한다 해도 paging과 혼합해서 사용한다.

Segmentation With Paging (segment와 page혼합)

이 방법은 segment가 통째로 물리메모리에 올라가지 않고 page 화 되어 메모리에 올라간다.
결국은 page 단위로 잘려 올라가기 때문에 메모리도 frame 단위로 잘려 관리된다.

os_10_22

Logical Address에서 STBR을 통해 segment table 의 해당 entry로 이동,
entry에서 segment마다 존재하는 page table base 를 얻는다,

s: segment 번호
d: offset, page 번호
p: 4KB로 나눈 값
d': 나머지
>=: segment lengthpage 10개로 구성되어 10*4KB인데 d가 이보다 크다면 trap를 발생시킨다.

의미단위로 나누어 장점도 얻고 외부조각도 생기지 않는다.