[운영체제/OS] 메모리 관리 - 물리적, 논리적 주소 공간과 스와핑(Swapping)

kindof

·

2021. 6. 14. 20:41

💡 0. 들어가면서

메모리 관리(Memory Management)는 하나의 물리적인(Physical) 메모리 공간에서 여러 개의 프로세스를 어떻게 돌릴 것인가에 대한 이야기인데요. 메모리 관리에 대해 공부하고 나면 아래 질문들에 대한 답을 할 수 있을 것 같습니다.

- 여러개의 프로세스를 하나의 메인 메모리 상에서 어떻게 돌릴 것인가?
- 프로세스마다 점유하고 있는 메모리 사이의 간섭을 어떻게 줄일 것인가?
- 적은 오버헤드를 추구하면서 어떻게 하면 메모리 공간을 낭비없이 효율적으로 활용할 것인가?

 

우선 이번 포스팅에서는 메모리 관리를 이야기하기 위한 기본적인 개념과 용어를 공부해보겠습니다.

 


📖 1. 주소 공간(Address Spaces)

메모리 관리에 대해 공부하기 위해 먼저 '주소 공간(Address Spaces)'라는 개념에 대해 알아보겠습니다. 주소 공간은 크게 두 가지로 나뉩니다.

  1. 물리적 주소 공간(Physical address space): 물리적 주소 공간은 하드웨어에 실제로 존재하는 주소를 의미하고, 메인 메모리가 512MB의 용량이라고 할 때 그 용량 자체를 의미합니다.
  2. 논리적 주소 공간(Logical address space): 논리적 주소 공간은 프로세스 관점에서 자신이 가지고 있는 메모리 크기를 의미합니다.

한편, 프로그램은 디스크에 Binary Executable File 형태로 존재하는데요. 프로그램의 실행은 곧 프로세스의 컨텍스트(Context)가 메모리에 올려지고, CPU에 의해 실행되는 것을 의미합니다.

 

즉, 프로세스가 실행되면 해당 프로세스가 가진 명령어(Instruction)들과 데이터를 메모리에 올려 사용하게 되고, 프로세스가 종료되면 메모리가 해제되어 다른 프로세스들이 메모리를 사용할 수 있는 것이죠.

 

이러한 관점에서 논리적 주소 공간과 물리적 주소 공간의 매핑은 아래와 같이 이루어집니다.

 

Logical Address, Physical Address

컴파일과 어셈블링 과정이 끝나면 Object 파일이 만들어지는데, 이 때 프로그램에는 논리적 주소(Logical address)가 부여됩니다. 이 때는 아직 프로그램 실행에 필요한 라이브러리들이 로드되지 않아서 실행 가능한 상태가 아니죠.

 

이후에 링킹(Linking) 과정이 일어나면 프로그램을 실행하기 위한 코드 조각들을 불러옵니다. 예를 들어 printf()함수를 호출하기 위해서는 실제 printf() 함수가 어느 라이브러리에 있고, 그 라이브러리를 찾아서 엮어주는 과정이죠.

 

마지막으로 프로그램이 실제로 로드되어 실행될 때, 물리적 주소(Physical address)에 매핑됩니다. 이 때, 물리 메모리에 할당되는 공간은 하위 메모리부터 채워져 나가며, MMU라는 하드웨어 레지스터에 의해 주소 변환이 이루어집니다.

 

 

🗒 2. 주소 변환을 위한 하드웨어 MMU

위에서 말한 것처럼, 프로세스의 논리적 주소는 실행 시점에 어떠한 하드웨어에 의해 물리적인 주소 공간으로 매핑되는데요. 

 

이 때, Relocation Register와 Limit Register라는 하드웨어가 주소 매핑에 사용되며, MMU register는 이 두 가지 레지스터의 값을 더하여 물리적 주소 공간을 지정해주는 레지스터를 말합니다.

 

무슨 말인지 아래 그림을 보면서 이야기해보겠습니다.

Registers for Address Mapping

Relocation register는 현재 사용 가능한 물리 메모리의 가장 하위 주소를 가지고 있으며, Limit register는 논리적 주소(Logical address)의 범위를 가지고 있습니다. 그러면 [Relocation register 값 ~ Relocation register 값 + Limit register 값]이라는 범위가 곧 논리적 주소가 물리적 주소에 매핑되는 구간이겠죠?

 

 

📬 3. 스와핑(Swapping)

Swapping : A process can be Swapped temporarily out of memory to a backing store, and then brought back into memory for continued execution.

Swapping은 메모리 관리를 하는 데 있어서 굉장히 기본적이고 중요한 개념인데요. 한정된 물리적 메모리 공간 안에 여러 프로세스 메모리를 올리기 위해서 기존 프로세스를 Backing store에 임시로 옮겨두고 다른 프로세스를 처리한 뒤, 다시 Backing store에서 프로세스를 불러오는 일련의 과정을 말합니다.

 

다시 말해서, 메인 메모리에 특정한 프로세스를 올려야 하는 상황에서 물리 메모리의 공간이 부족하면 이미 올려져 있는 어떤 프로세스를 다른 HDD 등에 옮겨두고 작업을 한 뒤, 다시 옮겨둔 프로세스를 불러와서 작업을 재개하는 것이죠. 이 때, Swapping을 위해 필요한 공간을 Backing store라고 합니다.

Swapping

한편 Swapping을 위해서는 프로세스의 메모리를 다른 공간에 옮겨야 하는데, 이 때 소요되는 시간을 Transfer Time이라 하며 이 시간은 Backing store로 사용되는 하드디스크는 램처럼 메모리에 대한 액세스 속도가 빠르지 않다는 점에서 꽤나 클 수밖에 없습니다.

 

예를 들어 유저의 프로세스 크기가 2048Kb, 데이터를 옮기는 속도가 1Mbps(1024kbps)라고 하면 Swapping을 하는 데 소모되는 시간을 2초(Swap-in) + 2초(Swap-out) = 4초나 걸립니다.

image

그러면 여기서 한 가지 궁금증이 생기겠죠? "Swapping을 하지 말아야 하나? 혹은 Swapping을 효과적으로 하는 방법이 있는건가?"


 

이번 포스팅은 메모리 관리 이슈를 공부하기 위한 기본적인 개념에 대해 공부했습니다. 다음 포스팅부터는 더 본격적인 이야기를 해보도록 하겠습니다.