-
[OS] Memory ManagementComputer Science/Operating System 2021. 8. 10. 08:38
프로그램을 실행하기 위해서는 프로세스를 메모리에 올려야 한다.
운영체제는 한정된 메모리 공간을 활용하기 위한 메모리 관리 전략을 지니고 있다
Logical Address(Virtual Address) : 프로세스마다 독립적으로 가지는 주소공간. CPU가 보는 주소. 각 프로세스마다 0번지 부터 시작
Physical Address: 메모리에 실제로 올라가는 위치
Address Binding
: Symbolic Address ➡ Logical Address ➡ Physical Address로 변환하는 과정
사용자 프로그램을 물리적 메모리에 직접 접근할 수 없기 때문에(권한을 가져서는 안 된다) 상징 - 논리 - 물리 주소로 바인딩하는 과정이 필요하다
주소 바인딩은 다음의 세 시점에 발생할 수 있다.
1️⃣ Compile time binding : 물리적 주소가 컴파일 시 알려진다. 컴파일러는 absolute code를 생성하기 때문에 주소를 바꾸고 싶다면 다시 프로그램을 컴파일해야 한다.
2️⃣ Load time binding : Loader의 책임 하에 물리적 주소를 부여하는 방식. 컴파일러가 relocatable code를 생성한 경우 가능하다.
3️⃣ Execution time binding : 수행이 시작된 이후에도 프로세스의 메모리 상 위치를 이동할 수 있다. CPU가 주소를 참조할 때 마다 binding을 점검한다. 하드웨어적 지원이 필요한 바인딩 방식이다.
MMU (Memory-Management Unit)
: logical address ➡ physical address로 매핑해 주는 hardware device
MMU scheme: 사용자 프로세스가 CPU에서 수행되며 생성해내는 모든 주소값에 대해 base register(=relocation register)의 값을 더한다
user program: logical address만을 다룬다(실제 physical address에 대한 접근X)
이 때 limit register가 필요한 이유는 무엇일까 ?
logical address가 프로그램이 할당한 메모리 영역 이상의 논리적 메모리 주소를 요구할 때, 자칫하면 다른 프로세스의 메모리 영역을 침범할 수 있다(옛날에 실제로 이를 악용한 해킹 사례가 존재했다고 한다)
그렇기 때문에
├ Relocation register(base register): 접근할 수 있는 물리적 메모리 주소의 최소값
└ Limit register: 논리적 주소의 범위 체크
를 두어 logical address를 physical address로 변환하는 과정이 필요하다
이제 프로그램의 메모리 적재 전략을 알아보자
1️⃣ Dynamic Loading
: 프로세스 전체를 메모리에 미리 다 올리는 것이 아닌 해당 루틴이 불려질 때 메모리에 적재하는 방식
- memory utilization을 향상시킨다
- 가끔씩 사용되는 많은 양의 코드일 경우 유용하다(ex. 오류 처리 루틴 등)
- OS의 특별한 지원 없이도 프로그램 자체에서 구현 가능
2️⃣ Overlays
: 메모리에 프로세스의 부분 중 실제 필요한 정보만을 올리는 방식
- 프로세스 크기가 메모리보다 클 때 유용하다
- 작은 공간의 메모리를 사용하던 초창기 시스템에서 사용자에 의해 구현되었다
+ Dynamic Loading과 Overlays 방식의 차이점: 프로세스를 전부 올리느냐 🆚 일부만 올리느냐
3️⃣ Swapping
: 프로세스를 일시적으로 메모리에서 backing store로 쫓아내는 기법
✅ Backing Store(Swap Area) ❔
- 디스크(많은 사용자의 프로세스 이미지를 담을 만큼 충분히 빠르고 큰 저장공간)
✅ Swap In / Swap Out ❓
- 일반적으로 중기 스케줄러(swapper)에 의해 swap out 시킬 프로세스 선정
- priority-based CPU scheduling algorithm
- priority가 낮은 프로세스를 swap out
- priority가 높은 프로세스를 메모리에 올려 놓음
- compile time 혹은 load time binding에서는 원래 메모리 위치로 swap in 해야한다
- execution time binding에서는 추후 빈 메모리 영역 아무 곳에나 올릴 수 있다
- swap time은 대부분 transfer time(swap되는 양에 비례하는 시간)이 소모된다
Dynamic Linking: Linking을 실행 시간(execution time)까지 미루는 전략
✔ Static Linking
- 라이브러리가 프로그램 실행 파일에 포함된다
- 실행 파일의 크기가 커진다
- 동일한 라이브러리를 각각의 프로세스가 메모리에 올리므로 메모리가 낭비될 수 있다
✔ Dynamic Linking
- 라이브러리가 실행 시점에 연결된다
- 라이브러리 호출 부분에 라이브러리 루틴의 위치를 찾기 위한 stub이라는 코드를 둔다
- 라이브러리가 이미 메모리에 있으면 그 루틴의 주소로 가고 없으면 디스크에서 읽어온다
- 운영체제의 지원이 필요하다
Allocation of Physical Memory - 물리적 메모리 할당 전략
물리적 메모리 공간은 아래와 같이 커널 / 유저 영역에 의해 분류할 수 있다
- OS 상주 영역: interrupt vector와 함께 낮은 주소의 영역
- 사용자 프로세스 영역: 높은 주소의 영역 사용
우리의 관심사는 "사용자 프로세스 영역에 다양한 프로세스들을 어떻게 적재할 지" 이다
✅ Contiguous Allocation : 각각의 프로세스가 메모리의 연속된 공간에 적재된다
ex) Fixed partition allocation, Valiable partition allocation
✅ Noncontiguous Allocation : 하나의 프로세스가 메모리의 여러 영역에 분산될 수 있다
ex) Paging, Segmentation, Paged Segmentation
단편화(Fragmentation)란 ❓❔❓❔
✅ Internal Fragmentation(내부 단편화): 일정 크기의 페이지에 프로세스를 할당할 시 프로세스의 크기가 페이지보다 작을 경우 발생
✅ External Fragmentation(외부 단편화): 메모리 내의 여유 공간이 여러 조각으로 나눠지는 현상. 프로그램이 기억장소의 남은 영역을 할당하고 해제할 때 발생. 조각이 너무 작아 활용할 수 없어 메모리가 낭비된다.
Fixed Partition(고정 분할 방식)
: 물리적 메모리를 몇 개의 영구적 분할로 나누는 기법
- 분할의 크기가 모두 동일한 방식과 서로 다른 방식 존재
- 분할 당 하나의 프로그램 적재
- 융통성 X (동시에 메모리 load 되는 프로그램 수 고정, 최대 수행 가능 프로그램의 크기가 제한됨)
- Internal Fragmentation, External Fragmentation 발생 가능
Variable Partition(가변 분할 방식)
: 프로그램의 크기를 고려해서 메모리 공간을 가변적으로 할당
- 분할의 크기 및 개수가 동적으로 변함
- 기술적 관리 기법 필요
- External Fragmentation 발생
Hole: 가용 메모리 공간. 프로세스가 도착하면 수용 가능한 hole을 할당. OS는 (할당 공간, 가용 공간)의 정보를 유지
Dynamic Storage - Allocation Problem
: 가변 분할 방식에서 size가 n인 요청을 만족하는 가장 적절한 hole을 찾는 문제 ❗❗
1️⃣ First-Fit: size가 n 이상인 것들 중 최초로 찾아내는 hole에 메모리 할당
2️⃣ Best-Fit: size가 n 이상인 가장 작은 hole을 찾아 할당. 많은 수의 아주 작은 hole들이 생성됨
3️⃣ Worst-Fit: 가장 큰 hole에 할당(위의 두 기법에 비해 속도 및 공간 효율이 떨어짐)
➕ Compaction: 외부 단편화 문제를 해결하는 한 가지 방법.
사용중인 메모리 영역을 한 군데로 몰고 hole들을 다른 한 곳으로 몰아 block을 생성
프로세스 주소가 실행 시간에 동적으로 재배치 가능한 경우에만 사용한다(비용 多)
'Computer Science > Operating System' 카테고리의 다른 글
[OS] 공유 자원의 접근을 제한하는 Process Synchronization (0) 2021.08.06 [OS] CPU Scheduling - 어떤 Job이 CPU를 선점할까 (0) 2021.08.02 [OS] Process Management와 System Call (2) 2021.06.13 [OS] Process and Thread - 프로세스와 쓰레드 개념과 차이점 (0) 2021.02.07 [OS] 운영체제(Operating System)의 개요 및 역할 (0) 2021.01.25