운영체제(OS) - 메모리 관리(Basic Memory Management)
Real Memory(Real Storage)
실제 메모리(주 기억장치)라고도 한다.
메모리는 CPU와 상호작용을 통해 CPU는 메인메모리에 주소로 접근하면 CPU는 메모리에서 해당 주소에 위치한데이터를 가져온다.
주소의 개수
128M의 Ram이 있을 경우
M(메가바이트) = 2의 20승
128 = 2의 7승
2^20 * 2^7 = 2^27만큼의 주소 개수가 사용된다.
재배치 문제
a와 b는 개별 프로그램의 메모리구조이며 각 메모리마다 0~16380의 메모리 영역을 차지한다..
a를 실행하면 0번이 실행되고 24번으로 점프한 후 나머지가 실행되고 끝난다.
b는 28번으로 점프해서CMP(비교)를 실행하고 프로그램이 끝난다.
이렇게 작성된 프로그램을 한개의 메모리에 적재를 시킨다. a가 낮은 주소 영역(흑색), b가 높은 주소 영역(흰색)이다.
한 메모리에 적재가 되었지만 프로그램을 수정해주지 않게 된다면 프로그램 a에선 문제가 없지만 프로그램 b에선 점프가 일어날 때 엉뚱한 프로그램인 a로 점프를 하게된다.
해당 프로그렘의 주소영역이 아닌 다른 프로그램의 주소 영역을 침범하게 되며 에러가 발생한다. 이게 재배치 문제.
재배치 문제 solution 1. 고정분할 Absolute Loading.
각 프로그램은 고정된 장소로 적재되게 된다.
파티션 별로 크기와 공간을 나누고 해당된 공간에 해당된 프로그램을 적재한다고 할 경우 문제가 생긴다.
파티션1은 10k의 공간을 차지하고, 파티션 2는 100k, 파티션 3은 1m의 공간을 차지한다고 할 경우 파티션2에 들어가야하는 프로그램은 당연히 파티션 1에 들어가지 못한다.
왜냐하면 공간이 부족하기 때문.
1. 파티션3이 비어있어도 파티션 2에 들어가야하는 프로그램은 파티션3에 들어갈 수 없다. 공간의 활용도가 매우 떨어진다.
2. 파티션2에 프로그램이 들어갔는데 90k만 차지하고 있더라도 남는 10k 공간에 다른 프로그램이 들어가지 못한다. 남는 10k의 메모리가 사용될 수 없다.
재배치 문제 solution 2. 고정분할 Relocatable Loading.
파티션을 크기별로 나눈다. 이후 프로세스는 공간이 충분하다면 어디든 들어갈 수 있다. 이러면 재배치 문제가 생기게 되는데 재배치 문제가 발생할 때 마다 주소값을 고쳐주어야 한다.
재배치와 보호
재배치(Relocation): 프로그램 코드와 데이터를 위한 적재 주소를 할당하고 코드 및 데이터를 할당된 주소에 적합하게 조정해주는것.
정적 재배치
- 프로그램을 적재할 때 참조하는 주소를 직접 수정해주는 것.
- IBM360의 Loader: 재배치가 이루어질 때 메모리의 주소들을 바꿔주는 프로그램
동적 재배치 및 보호를 위한 해결
base와 limit값을 사용한다.
실제 물리적 주소의 한계값은 base값에 address를 더한 것인데, 재배치가 이루어 질때 address >= limit이면 error를 발생한다.
주소의 종류
Logical address
- 프로세스마다 독립적으로 갖는 공간.
- 논리적인 주소 체계로, 0번지를 시작으로 상대적인 주소 값을 갖는다.
- CPU에서 인식하는 주소 체계이다.
- virtual / relative / relocatable address 라고도 한다.
Physical address
- 실제 물리적인 메모리 위치를 식별하는 주소
- absolute address라고도 한다.
Symbolic address
- 변수나 함수와 같이 코드에서 사용하는 상징적인 이름을 주소로 사용하는 방법 -> 프로그래머가 이해하기 쉽다
Address Binding
만약 프로그램에다가
int a = 2
이런 코드를 쓰면 a라는 번지에 2를 쓰는(write)것.
근데 실제로 CPU가 명령을 수행하면
store #4920, 2 //(4902는 임의의 주소)
이렇게 되는데, 이 #4920이란 메모리 번지를 언제 결정하느냐가 크게 3가지가 있다.
1. compile time binding,
2. load time binding
3. execution time(Run-time)
이 메모리 번지를 언제 어떻게 결정 하느냐가 어드레스 바인딩, 주소할당이라고 한다. -> 한 주소 공간에서 다른 주소공간으로 매핑하는 과정
Compile time binding
- 컴파일 시간(Compile time)에 물리 주소를 결정하는 것으로, 실행 파일에 물리주소를 포함시킨다.
- 논리주소와 물리주소가 같다.
프로그램에 절대주소(Physical address)가 포함되어 있으므로 프로세스를 로드하는것이 빠르지만, 생성된 주소공간이 다른 프로그램에 의해 점유되어 있을 경우 충돌이 발생할 수 있기 때문에, 프로그램을 다시 컴파일 해야하는 상황이 생긴다.
이러한 이유로 다중 프로그래밍이 가능한데 현대 OS환경에선 실효성이 떨어져 사용하지 않는 방법이다.
Load time binding
- 로드 시간에 논리주소를 물리주소로 바인딩하는것.
- Loader에 의해 재배치 가능한 주소가 절대 주소로 변환된다.
- 컴파일러가 주소를 결정할 수 없는 경우 symbolic address를 Logical address로 변경한 후 Loader에 의해 Physical address로 변경한다.
Execution time(Runtime) binding
- 실행 시간에 논리주소를 물리주소로 바인딩 하는 것.
- 현대 OS는 대부분 이 방식을 사용.
- MMU(Memory Management Unit)장치에 의해 논리주소를 물리주소로 변경한다.
Swapping
너무 많은 프로세스가 있을경우 메모리가 충분하지 않게 됨 -> Trashing이 발생함.
프로세스가 실행되려면 반드시 메모리에 올라가야 한다.
Trashing이 발생하면 사용하지 않는 x번 프로세스를 잠시 보조기억장치에 옮겨둔다. -> Swap-out(roll-out)
시간이 지나고 x번 프로세스에 이벤트가 도착했다면 다시 메모리에 올려줘야 한다. -> Swap-in(roll-in)
이런 Swap-in, Swap-out을 반복하는 일을 Swapping이라고 한다.