0.🚶들어가며

모든 프로그램은 메인 메모리에 올라와서 실행됩니다. 메모리는 한정된 자원으로 이를 활용하는 방법에 따라 성능에 큰 영향을 줄 수 있습니다.

 

오늘날 시분할 시스템에서 운영체제를 포함한 여러 프로그램들이 메모리에 올라와 실행되기 때문에 이를 관리하는 일은 쉬운 개념이 아닙니다. 메모리에 올라가는 프로세스 입장에서는 자신의 작업이 편리해지길 원하며 메모리를 관리하는 관리자 입장에서는 관리의 편리함을 원하죠. 프로세스와 메모리 관리자 각각의 상충되는 요구를 어떻게 타협해나가며 오늘날의 메모리 관리 시스템을 만들어 나아가는지에 대해 알아보도록 하겠습니다.


1.📖메모리 관리자 (MMU)

메모리 관리는 메모리 관리자가 합니다. 메모리 관리자는 MMU(Memory Manage Unit)이라는 하드웨어입니다. MMU는 크게 세가지 작업을 한다고 볼 수 있습니다. 각 작업에 대해서 알아보도록 하겠습니다.

1) Fetch (가져오기)

Fetch는 프로세스와 데이터를 메모리로 가져오는 작업입니다. 사용자가 요청한 프로세스와 데이터를 모두 메모리로 가져오기도 하고, 일부만 가져오기도 하며, 요청이 없더라도 앞으로 필요할 것이라고 예상되는 데이터를 미리 가져오기도 합니다. 

2) Placement (배치)

Fetch로 가져온 프로세스와 데이터를 메모리 어디에 놓을지 결정하는 작업입니다. 배치를 잘라서 할지, 어떻게 자를지 등을 결정하기도 하죠. 자르는 방식에 따라 페이징, 세그먼테이션 등의 방법이 있으며 각 방법마다 장단점이 존재하여 이를 고려해야 합니다. 한정된 메모리를 효율적으로 사용하는 것은 시스템 효율을 좌우하는 중요한 요소입니다.

3) Replacement (재배치)

재배치 작업은 새로운 프로세스를 배치해야하는데 메모리가 꽉 찬 경우 어떤 프로세스를 쫓아낼 것인지에 대한 작업입니다. 많이 사용할 프로세스를 내쫓으면 재배치 작업이 자주 일어나 비효율적이게 됩니다. 쫓아낼 프로세스를 적절히 찾아내기 위해 보통 교체 알고리즘을 사용합니다.  


2.📚메모리 주소

메모리에 접근할 때는 주소를 이용합니다. 따라서 메모리와 주소는 매우 밀접한 관계이죠. 이에 대해 알아봅시다.

1) 32bit CPU와 64bit CPU

CPU의 비트는 한 번에 다룰 수 있는 데이터의 최대 크기입니다. 32bit CPU의 경우 한번에한 번에 32bit를 64bit CPU의 경우 한 번에 64bit를 다룰 수 있는 것이죠. 또한 레지스터와 같은 CPU 내부 부품은 CPU의 비트를 기준으로 동일하게 제작됩니다. 32bit CPU의 ALU도 한 번에 32bit를 처리할 수 있도록 설계되고, 각종 버스의 대역폭도 32bit만큼 이동할 수 있게 만들어지는 것입니다. 

 

CPU의 비트는 메모리 주소 공간의 크기와도 관련이 있습니다. 32bit CPU의 메모리 주소 레지스터의 크기는 32bit입니다. 따라서 32bit로 표현할 수 있는 수의 개수는 2^32개이며 각 수마다 1byte의 메모리 한 곳을 표현하고 있다면 약 4GB의 메모리를 사용할 수 있는 것 입니다. 

2) 절대 주소와 상대 주소

메모리 주소에는 절대 주소상대 주소의 개념이 있습니다. 절대 주소는 실제 메모리의 물리 주소 공간이며 하드웨어 입장에서 바라본 주소입니다. 그렇다면 상대 주소는 무엇일까요? 

 

사용자 프로그램은 컴파일 될 당시 자신이 메모리 어느 위치에 올라갈지 알 수 없습니다. 만약 물리 주소 공간을 미리 정해놓고 프로그래밍을 하게 된다면 해당 주소 공간에 다른 프로세스가 있을 시 심각한 오류를 유발할 수 있습니다. 사용자 입장에서 절대 주소는 어렵고 불편한 존재인 것이죠. 이에 상대 주소라는 개념이 등장합니다.

 

상대 주소는 사용자 프로세스 입장에서 바라본 주소입니다. 절대 주소와 관계없이 항상 0번지에서부터 시작하는 주소이죠. 이를 논리 주소공간이라고도 합니다. 프로세스는 0번지부터 시작한다고 가정하며 실행할 테니 알아서 바꿔줘라 하는 것입니다. 

 

그렇다면 상대 주소를 기준으로 작성된 프로그램들이 실행될 때 이를 절대 주소로 변환해주는 시스템이 있어야할 것입니다. 이를 메모리 관리자가 처리해주는 것입니다. 아래와 같은 순서대로 그 과정이 진행되죠.

  •  사용자 프로세스가 상대 주소 xx 번지에 있는 데이터를 요청한다
  • CPU는 메모리 관리자에게 xx 번지에 있는 내용을 가져오라고 명령한다
  • 메모리 관리자는 재배치 레지스터를 사용하여 상대 주소 xx 를 절대 주소 (xx + 재배치 레지스터 값)으로 변환하고 절대 주소에 있는 메모리 데이터를 가져온다.

위 과정에서 나온 메모리 관리자의 재배치 레지스터가 상대주소를 절대 주소로 변환해주는 것입니다. 재배치 레지스터 값만 조절해준다면 누구든 상대 주소를 써도 안전하게 절대 주소에 접근할 수 있게 되는 것이죠.


3.😀단일 프로그래밍 환경에서의 메모리 할당

단일 프로그래밍 환경에서는 메모리 관리가 비교적 단순합니다. 운영체제 영역 이외에 구역에 프로그램을 올려두면 되기 때문이죠. 하지만 만약 메모리의 크기보다 프로그램의 크기가 더 크다면 어떻게 해야 할까요?

1) 메모리 오버레이

프로그램의 크기가 물리 메모리 크기보다 클 때 전체 프로그램을 적당한 크기로 잘라 가져오는 기법을 메모리 오버레이라고 합니다. 프로그램을 몇 개의 모듈로 나누고 필요할 때마다 모듈을 메모리에 가져와 사용하는 방법이죠. 어떤 모듈을 가져올지는 CPU 레지스터 중 하나인 프로그램 카운터(PC)가 결정합니다. PC가 가리키는 명령이 메모리에 없으면 메모리 관지라에게 요청해 해당하는 모듈을 메모리에 가져오게 합니다. 

 

메모리 오버레이 방식은 프로그램 전체를 메모리에 올려놓고 실행하는 것보다 느리지만 한정된 메모리에서 메모리보다 큰 프로그램의 실행이 가능하다는 점은 충분히 의미가 있습니다. 

2) 스왑

메모리 오버레이 과정에 연장선인 스왑 개념은 메모리에서 쫓겨난 프로그램 조각을 어디에 둘 것인지에 대한 내용입니다. 메모리에서 쫓겨난 프로세스는 저장장치의 특별한 공간에 모아두는데 이를 스왑 영역이라고 합니다. 그리고 스왑 영역에서 메모리로 가져오는 작업을 스왑 인(Swap In), 쫓아내는 과정을 스왑 아웃(Swap Out)이라고 부릅니다. 또한 이 부분을 관리하는 게 프로세스 스케줄링에서 살펴보았던 중기 스케줄러입니다.

 

스왑 영역의 특이한 점은 저장 장치이면서 메모리 관리자가 관리한다는 점입니다. 저장 장치는 원래 저장장치 관리자가 관리하지만 스왑 영역은 메모리에서 쫓겨났다가 다시 돌아오는 데이터들이 머무는 곳이기 때문에 저장 장치는 장소만 빌려주고 메모리 관리자가 관리하는 것입니다.


4.💨나가며 

이번 글에서는 메모리 관리와 관련된 개념을 알아보고 단일 프로그래밍 환경에서의 메모리 할당 관련 내용에 대해 알아보았습니다. 다음 글에서는 다중 프로그래밍 환경에서의 메모리 할당에 대해 알아보겠습니다.

반응형
복사했습니다!