[운영체제] 3. Memory Virtualization - (1) Address Spaces ①
Memory Virtualization(메모리 가상화) 파트는 원래 공룡책과 같은 곳에서는 Memory management라는 이름으로 소개되곤하는 파트라고 알아줬으면 한다.
시험공부하다가 머릿 속에 정리하면서 블로깅을 하다보면 더 정리가 잘 될 것 같아서 써보는 글이다.
컴퓨터에서 '메모리'라는 곳은 4차원 주머니 없는 도라에몽과 같다고 생각하면 된다.
도구들을 사용하는 주체는 비록 '도라에몽' 이지만, 아무리 도라에몽이라고 하더라도 도구 없이는 파란 너구리고양이기 때문이다.
아무튼, 폰 노이만 아저씨의 컴퓨터 구조에 의해서 프로그램은 실행에 있어서 필요한 코드와 데이터들은 반드시 메인 메모리에 저장되어야만 한다.
프로그램 실행을 한 이후에는, 이를 '프로세스' 라고 부르고, 이는 자신만의 주소 공간(address space)가 필요하다.
하지만, 메모리 자체는 상당히 비싼 시스템 자원이기 때문에 소중한 메모리를 애껴애껴서 사용해야 한다.
1. "프로세스입니다. 주소가 어디라구요? 뭔 파티션?"
한국인은 모름지기 배달의 민족이다. 그럼 당연히 가장 중요한 것이 메뉴도 메뉴지만, 주소가 가장 중요할 것이다.
"아주대학교"로 배달을 시키려고 하면 "아주대학교로 갖다주세요~" 보다는, "수원시 영통구 월드컵로 206 OOO으로 갖다주세요~"라고 우리는 말하곤 한다.
주소를 말하는 것이 옛날부터 전해 내려오는 일반적인 규칙이기 때문이다. 컴퓨터의 데이터도 마찬가지이다.
컴퓨터에는 두 가지 주소가 존재한다. 하나는 물리적 주소(Physical Address), 다른 하나는 논리적 주소(Logical Address) 혹은 가상 주소(Virtual Address)이다.
1.1 물리적 주소(Physical Address) & 논리적 주소(Logical Address)
물리적 주소는 컴퓨터의 배열로 따지면 하나의 인덱스, 실제 상황으로 따지면 '수원시 영통구 월드컵로 ...'와 같다.
반대로 논리적 주소는 CPU에 의해서 생성되는 주소를 말한다. 예를 들어, 아주대학교 학생이 아주대학교 병원이 어디있는지에 대해서 떠올릴 때에는 '수원시 영통구 ... ' 보다는, '아주대학교 옆!' 이라고 더 잘 떠올릴 것이다. 이때 학생이 CPU, 아주대학교 병원이 데이터라고 생각하면 편할 것 같다.
굳이굳이 가상 메모리를 사용하는 이유는, 위에서 언급했던 것처럼 메모리를 더 효율적으로 사용하기 위해서라고 생각한다.
'아주대학교'라는 대상을 떠올릴 때, '도로명 주소'라는 특수한 조건을 더 외우는 것보단, '나에게서 얼마나 떨어졌는지를 직관적으로' 표현하는 방식이 더 기억 저장 공간을 효율적으로 사용할 수 있을 것이기 때문이다. 물론, 두 가지 다 좋은 방법이다.
우리는 뇌라는 좋은 하드웨어이자 소프트웨어가 있어서 논리적 주소를 쉽게 도로명 주소로 바꿀 수 있지만, 컴퓨터는 이를 MMU(Memory-Management Unit)를 통해서 실현한다.
그럼 주소에 대한 내용은 다 설명이 되었으니, 메모리 시스템에 대한 관리가 어떻게 이루어지는 지에 대해서 공부해보자.
1.2 Fixed Partition(고정 분할법) : "그 손님 수는 잘 모르겠고, 일단 저기 앉아봐유"
지금부터는 실행되는 프로세스가 시스템의 어떤 메모리에 올라가서 실행(동작)하는지에 대해서 알아볼 것이다.
기본적으로 이러한 방법이 지속적으로 연구되는 이유는 우리는 컴퓨터를 사용할 때 여러 개의 프로세스를 거의 동시에 사용(Multiprogramming)하기 때문인 것이다.
가장 간단한 방법은 Fixed Partition을 사용하는 방법이다. 초창기의 컴퓨터는 이 방식을 사용하곤 했다고 한다.
이를 어김없이 등장하는 우리 김교수님의 예시부터 가져와 설명하면 다음과 같다.
구내식당에 들어갔다. 근데, 테이블은 항상 4인 테이블(partition)으로 고정되어 있다. 손님들은 합석을 원하거나 본인 무리와 떨어져 나가기를 원하지 않는다.
그런데 식당 아주머니가 상당히 불친절해서 일단 손님이 오면 앉게 만드는 정책을 시행한다고 해보면 딱 Fixed Partition이다.
굉장히 간단한 식당 운영 방식이지만, 4명보다 많은 무리의 단체손님이 오면 서운해할거고, 4명보다 적은 커플 손님이 오면 내가 서운할 것 같다. 빈 테이블이 남아 손님을 받는 데 잉여 공간이 생길 것이다.
우선 physical memory를 일정한 크기(partition)으로 쪼개놓는다. (핵심 아이디어)
이때, physical address는 base address 주소와 logical address의 합(physicall address = base address + logical address)으로 매핑된다.
이때, 하나의 partition에는 하나의 process만 배치될 수 있고, partition이 생성된 개수는, Multiprogramming된 정도라고 이해하면 된다. (많이 실행될 수록, 많이 생성되겠지?)
위의 그림을 설명해보면, 프로세스에 따라 Base register가 정해지고 MMU는 이 Base register에 따라서 Logical Address를 적당한 Physical Address에 매핑하는 굉장히 단순한 아이디어이다.
Fixed Partition 방법의 장단점은 다음과 같다.
- 장점
- 구현하기 쉽다.
- Access에 대한 검증이 쉽다.
- context switching 하는 데에 있어서 유리하다.
- 단점
- partition의 크기 : 하나의 고정된 사이즈가 프로세스와 대응되면 좋겠지만, 그렇지 않은 경우가 많다.
- internal / external fragmentation 이 발생할 수 있다.
⚡ Internal / External fragmentation (내부/외부 파편화) 이란?
앞서 설명했듯이, Fixed Partition은 Partition이라는 공간이 '고정된' 곳이다. 따라서, 프로세스의 크기가 partition과 딱 맞으면 좋지만, 프로세스의 종류가 다양하기 때문에 때로는 partition보다 작을 경우도, partition보다 클 경우도 있을 것이다.
① partition보다 프로세스의 크기가 작아서 partition이 남는 잉여 공간이 생기는 경우를 internal fragmentation,
② partition보다 프로세스의 크기가 커서 partition이 넘칠 때를 external fragmentation이라고 한다.
위와 같은 이유로 식당 사장님과 시스템 프로그래머는 생각했다. '아. partition이 process의 크기에 따라 동적으로 생기면 어떨까...?'
1.3. Variable Partition(가변 분할법) : "몇 명이라고? 기다려봐 금방 테이블 만들어줄랑께"
위와 같은 호기심과 상상력으로 인해서 생겨난 Partition 방법이다. 또 한 번 예를 들어보겠다.
머리를 써본 구내식당 사장님은 오는 손님들마다 수에 맞는 크기의 테이블을 펼쳐서 사용하고자 하신다.
원래는 1인용 식탁이었던 것이 갤럭시 ZZZZ플립플립플립플립처럼 한 칸씩 늘어난다고 생각해보자.
그러면 처음에 들어온 손님들은 본인의 수대로 식탁이 만들어져서 기분이 좋게 식사를 할 것이다.
처음에 들어온 손님이 4인 테이블, 두 번째가 2인 테이블, 세 번째가 6인 테이블이 필요한 손님들이었고, 세 팀으로 식당이 2자리만 남고 꽉찼다고 가정해보자.
그러다가 2인 테이블이 먼저 식사를 마치고 계산을 하고 식당을 떠났다.
그 이후, 4명의 단체손님이 식당에 들어와서 "앉을 자리 있나요?"라고 물어보았다.
이때, 식당은 4명이 앉을 자리는 있었지만, 4인 테이블로 이어붙일 수 없을 만큼 테이블이 멀리 떨어져 있어서 손님을 받을 수 없었다.
이를 컴퓨터에서 똑같이 구현한 것이 바로 Variable Partition이다.
프로세스에 맞게 Base register가 정해지면, 프로세스의 Logical address를 읽어와서 Physical address에 매핑시킨다.
이는 단순히 빈 공간을 찾아 적재하는 것으로, 영어로는 'allocate a contiguous chunk from holes'라는 표현을 사용한다.
위의 방법을 사용한다면, 적어도 1.2.에서 문제점으로 지적되었던 Internal Fragmentation 문제점이 발생하지는 않을 것이다.
하지만, 위 그림에서도 볼 수 있듯이 Process가 할당되지 않았음에도 충분한 공간이 나오지 못해 새 프로세스를 할당하지 못하는 경우(external fragmentation)가 발생할 수 있다.
따라서 그 사이의 공간을 어떻게 사용할 것인지에 대해서도 해결하는 것이 엔지니어의 역할이기에 이에 대한 의견 또한 분분하다. (Allocation Strategies)
🧐 Allocation Strategies (할당 전략) 이란?
Variable Partition 기법에서, '모든 프로세스의 배치 이후에 빈공간이 생길 때, 새로운 프로세스가 들어오면 어디에 배치하는 것이 가장 이상적일까?' 를 상상하는 전략이다.
① First Fit (최초 적합) : 충분히 큰 크기를 가진 첫 번째 partition을 선택한다. (들어오는 프로세스가 들어갈 수 있는 physical memory의 공백을 만나면 그곳으로 들어가는 전략)
→ 구현 자체도 간단하고, Overhead 또한 작지만, 최상의 공간 활용 방법은 아니다.
② Best fit (최적 적합) : 프로세스가 들어갈 수 있는 partition 중, 가장 작은 곳을 선택한다.
→ 최적의 공간만을 추구하기 때문에 공간 활용도가 최상이지만, 작은 프로세스에 대비한 partition 확보가 어렵고, Overhead가 크다.
③ Worst fit (최악 적합) : 프로세스가 들어갈 수 있는 partition 중, 가장 큰 곳을 선택한다.
→ 자잘자잘한 partition 발생을 줄일 수 있지만, 큰 프로세스에 대비한 partition 확보가 어렵고, Overhead가 크다.
이번 포스팅에서 설명한 partition에 대해서 결론을 지어보겠다.
partition은 프로세스당 딱 하나씩 할당되어서
- 배치하고 관리하기 힘들고,
- 증가 및 감소시키기 어려우며
- 시스템적으로 보안도 쉽지 않다.
(스포) 그래서 등장한 개념이 바로 Seg...... (다음 포스팅에서 계속)
이 글이 많은 사람들에게 도움이 되었으면 좋겠다. 😊