레지스터, 캐시는 HW가 관리
메인메모리, 보조기억장치는 SW(OS)가 관리
Block
보조 기억장치와 주 기억장치 사이의 데이터 전송 단위
Size: 1~4KB
Word
주 기억장치와 레지스터 사이의 데이터 전송단위 (데이터버스의 크기)
Size: 16~64bit
즉 주기억장치에서 보조기억장치의 1비트만 읽더라도 Block단위인 4KB로 가져와야 한다.
프로그램의 논리 주소를 실제 메모리의 물리 주소로 매핑하는 작업
int a를 선언했다면, a가 논리 주소이다.
이 a를 메모리의 실제 주소로 매핑하는 작업이 Address Binding이다.
Adress Binding은 Binding 시점에 따른 구분이 가능하다
Compile time binding: 컴파일 시점에 바인딩
Load time binding: 프로그램을 메인메모리에 올릴 때 바인딩
Run time binding: 프로그램 실행 중에 바인딩
프로그램이 실행될 때 다음과 같은 과정을 거친다.
1. 소스코드를 오브젝트 파일로 변환하는 컴파일
2. 오브젝트 파일을 로드 모듈(.exe 실행파일)로 변환하는 링킹
3. 로더로 인해 로드 모듈을 메모리에 올리는 로드
4. 실행
프로세스가 메모리에 적재될 위치를 컴파일러가 알 수 있는 경우(위치변경 x)
프로그램 전체가 메모리에 올라가야 함
메모리 적재 위치를 컴파일 시점에서 모르면 대체가능한 상대주소를 생성
ex) 시작 주소 u를 기준으로 들어, 다른 변수는 u+100, u+200 등으로 상대적으로 생성
상대주소는 0에서 시작하되, 메모리에 프로그램이 올라가고, 그 시작주소가 400이라면
상대주소에 400을 더한 주소에 할당하는 방식
load time에 시작 주소를 반영하여 사용자 코드 상의 주소를 재설정
프로그램 전체가 메모리에 올라가야 함
Address binding을 수행시간까지 연기(프로세스 상태 Running일때)
프로세스가 block상태가 되었다가 다시 running이 될때마다 다시 Address binding을 수행한다
즉 프로세스가 수행 도중 다른 메모리 위치로 이동할 수 있다.
HW의 도움이 필요하며 (MMU: Memory Management Unit)
대부분의 OS가 사용하는 방식이다
프로그램의 모든 부분을 전부 메모리에 올리는것이 아닌, 필요한 부분의 메모리만 욜린다.
모든 루틴(Function으로 생각해도 무방)을 교체 가능한 형태로 디스크에 저장하며
실제 호출 전까진 루틴을 적재하지 않는다.
메인 프로그램만 메모리에 적재하여 수행하며, 루틴의 호출 시점에 address binding을 수행한다.
메모리 공간을 효율적으로 사용할 수 있다.
프로세서 할당이 끝나고, 수행 완료된 프로세스는 swap-device로 보내고(swap out)
새롭게 시작하는 프로세스는 메모리에 적재한다(Swap in)
Countinous Memory Allocation: 프로세스를 하나의 연속된 메모리공간에 할당
Non-Countinous Memory Allocation: 프로세스를 비 연속된 메모리공간에 할당
프로세스를 하나의 연속된 메모리공간에 할당하는 정책
프로그램, 데이터, 스택 등에 사용한다.
메모리에 동시에 올라갈 수 있는 프로세스의 수가 1인 경우
즉 하나의 프로세스만 메모리 상에 존재한다. 가장 간단한 메모리 관리 기법이다
프로그램의 크기가 메모리의 크기보다 크다면 Overlay structure을 사용해야 한다
Overlay structure
메모리에 현재 필요한 영역만 적재
사용자가 프로그램의 흐름 및 자료구조를 모두 알고 있어야 함(어렵다)
모든 시점에 사용하는 공통루틴은 항상 메모리에 올라가고,
어떤 시점엔 1번 루틴만 사용한다면 2번은 올리지 않고 1번만 올려두는 식
경계 레지스터Boundary register
프로그램이 메모리의 커널 영역을 침범하지 않게 보호하는 역할을 수행한다.
Uni programming은 메인메모리의 크기가 넓어도, 한개의 프로그램만 수행 가능하므로
메인메모리가 낭비된다(Low system resource utilization)
이를 해결하기 위해 Multi programming이 사용된다.
Multi-programming
Fixed Partition(FPM)
Variable Partition(VPM)
메모리 공간을 고정된 크기로 미리 분할해 둔다.
각 프로세스는 하나의 파티션에 적재한다 Process : Partition = 1:1
한번에 실행할 수 있는 프로그램의 수는 곧 파티션의 수가 된다.
각 파티션의 정보는 Table 자료구조를 통해 만들 수 있고 이를 Partition Table 혹은 State table이라 한다
파티션 이름, 시작주소, 크기, 현재 등록된 프로세스 ID등을 저장한다
Boundary regster을 통해 커널뿐 아니라, 파티션과 파티션들 사이에도 서로 침범하지 않도록 보호한다.
Fragmentation(단편화)
Internal Fragmentation(내부 단편화)
파티션 크기가 Process크기보다 클 때, 낭비되는 공간
ExternalFragmentation(외부 단편화)
남은 메모리 크기가 Process들의 총 합보다 크지만, 연속된 공간이 아니라 프로세스를 적재할 수 없는 상황
즉 Fixed Partition은 메모리 관리가 간편해 Overhead가 적지만,
단편화 현상들의 발생으로 메모리가 낭비될 수 있다.
변할 수 있는(유동적인 크기의) 파티션
초기에는 전체가 하나의 영역이지만,
프로세스를 처리하는 과정에서 메모리 공간이 동적으로 분할된다
프로세스가 요구하는 메모리 크기만큼만 할당하여 내부 단편화가 생기지 않지만
외부 단편화는 존재한다.
배치전략Placement Strategies
위 상황일때, 5mb짜리 프로세스를 3개의 남은 공간 중 어디에 배치할지 고려해야 한다.
이것을 배치하는 방법이 배치전략이다
배치전략의 종류
First-fit(최초적합)
Best-fit(최적 적합)
Worst-fit(최악 적합)
Next-fit(순차 최초 적합)
배치전략 사이의 우열은 가리기 힘들다. 상황에 맞는 배치전략 선택
First-fit(최초적합)
메모리 적재가 가능한 첫번째 파티션을 선택하는 방식(처음 발견된 적합한 파티션에 적재)
간단하고 overhead가 적지만, 공간활용률이 떨어질 수 있다.
Best-fit(최적 적합)
메모리 적재가 가능한 파티션들 중에 가장 작은 곳을 선택한다
모든 파티션을 살펴봐야 하므로 탐색시간이 오래걸린다
크기가 큰 파티션을 유지할 수 있지만,
활용하기엔 너무 작은 크기의 파티션이 많이 발생한다.
Worst-fit(최악 적합)
메모리 적재가 가능한 파티션들 중에 가장 큰 곳을 선택한다
모든 파티션을 살펴봐야 하므로 탐색시간이 오래걸린다
작은 크기의 파티션 발생을 줄일 수 있지만
크기가 큰 파티션을 유지할 수 없다,
Next-fit(순차 최초 적합)
마지막으로 사용한 메모리 위치부터 탐색을 시작한다(최초적합)
메모리 영역의 사용빈도를 균등화할 수 있다
(위에서부터 탐색을 시작하니, 메모리 위쪽 위주로 사용될 가능성 높으므로)
overhead가 적다
Variable Partition의 외부단편화 해결
Coalescing holes(공간통합)
Storage Compaction(메모리 압축)
인접한 빈 영역을 하나의 파티션으로 통합하는 방식이다.
프로세스가 메모리를 release하고 나가면 수행하며, overhead가 적다
하지만 빨리 해결해야 하는 프로세스가 기다려야 한다는 단점이 존재한다.
떨어져 있는 프로세스들을 모두 끌어올려 인접하도록 만든다.
이 경우 위치가 바뀌는 프로세스들을 잠시 멈춰야 한다. 즉 overhead가 매우 크다
따라서 자주 수행하지 못하고, 일정 시간마다 혹은 요청이 있을때만 수행한다.