운영체제가 담당하는 기능 중 하나인 메모리 관리는 쾌적한 프로그래밍과 overhead를 최소화하고 성능을 극대화하기 위해 꼭 필요한 기능이다.


따라서 운영체제는 실행되고 있는 작업(프로세스)들에게 메모리를 적절히 분배하며 작업이 끝나면 할당한 메모리를 회수한다.


운영체제에서 대표적인 메모리 관리 기법으로는 CMA, Paging, Segmentation 등이 있는데,

이 기법들은 메인 메모리(M·M)에 작업들을 어떻게 할당하느냐에 따라 그 성격이 나뉘게 된다.


하나하나 알기쉽게 같이 공부해보도록 하자.



CMA (Contiguous Memory Allocation)

영어로 쓰면 상당히 어려운 개념으로 보이지만, 연속 메모리 할당이라고 간단하게 해석할 수 있다.


프로세스가 실행될 때 프로세스는 OS에게 메모리를 요청한다.

만약 메모리 공간 상에 요청한 만큼의 공간이 남아있으면 메모리를 할당해 주지만, 그렇지 않다면 그만큼의 메모리가 생길 때 까지 기다려야 한다.


CMA방법으로 메모리를 할당해준다는 것은 남아있는 메모리를 계산할 때 따로따로 떨어져있는 메모리를 합쳐서 계산하는 것이 아니라

연속적인 메모리 공간을 계산한다는 것이다.


이른바 작업들을 할당할 때 작업을 분할하지 않고 통째로 메모리에 올린다는 뜻인데, 그림을 한번 살펴보자.


 메인 메모리

              5K

 Job.1    3K 

              2K

 Job.7    5K

 Job.3   4K

             3K

 Job.5    5K


이런식으로 메모리가 할당되어있다고 하자. 작업은 1, 3, 5, 7이 각각 3K, 5K, 4K, 5K만큼 할당되어 있고 비할당 메모리는 총 10K이다.  


이제 Job.11 이 실행하고자 OS에게 6K만큼의 메모리를 요구했다.

CMA 방법에서는 Job을 분할하지 않기 때문에 현재로써는 들어갈 공간이 없다.


따라서 Job들을 메모리 상에서 이동시켜 6K 이상의 공간을 만들어줘야 한다.

이 때 원칙은 가장 적은 메모리 이동으로 하나의(One single hole) 여유공간을 만들어줘야 한다는 것이다.

이 과정을 컴팩션(Compaction)이라고 하는데, 위의 예시를 Compaction시킨 결과는 다음과 같다.


 메인 메모리

              5K

              3K 

              2K

 Job.7    5K

 Job.3   4K

 Job.1    3K

 Job.5    5K


Job.1 을 Job.3 과 Job.5 사이의 빈 공간에 넣어줌으로써 최소한의 이동으로 하나의 여유공간을 만들었다.


이처럼 메모리에 작업단위로 프로세스를 할당시키면 작업이 끊기지 않고 논리적으로 잘 수행될 수 있다는 장점이 있지만,

메모리 공간이 부족할 때 Compaction을 하는 과정에 있으면 작업이 중단되며 오버헤드가 발생한다.


또한 비용도 많이 들기 때문에 실상 잘 사용하지 않는 메모리 관리 기법이라고 할 수 있겠다.



Paging

페이징 기법은 메인 메모리를 일정한 사이즈의 할당공간인 frame으로 쪼갠 뒤 프로세스도 그 크기에 맞게 나누어 할당하는 기법을 말한다.

frame 사이즈에 맞춰 프로세스를 나눈 단위를 page라고 하는데, 이 페이지들은 페이지 테이블에 순서에 따라 저장된다.


하나의 프로세스는 하나의 페이지 테이블을 갖고, 테이블은 인덱스와 내용으로 구성되어 있는데 

인덱스는 페이지의 순서를, 내용은 메인 메모리에 들어가는 위치를 가지고 있다.

그림을 보면서 이해해보도록 하자.


위와 같이 프로세스는 페이지 네 개로 나뉘고 테이블은 페이지의 인덱스를 메모리의 위치에 맞춰 저장하는 것이다.


이처럼 페이징은 메인 메모리가 일정한 단위로 나누어져있기 때문에 추가적인 메모리 할당이 요구될 때 Compaction을 할 필요가 없다.


하지만 논리적으로 같은 메모리 영역에 있어야 할 작업들이 나누어지므로 작업을 수행할 때 메모리를 탐색하기 때문에 오버헤드가 발생한다는 단점이 있다.

heap, stack, function과 같은 요소가 논리적인 작업에 속한다.


또한 만약 3.8K의 프로세스가 있다면 1K씩 페이지를 할당한다고 했을 때 0.2K가 남는 것처럼 불필요한 공간이 생길 수 있는데

이를 internal fragmentation(내부 단편화) 라고 한다.

이를 해결하기 위해서 0.1K 씩 페이지를 할당하게 된다면 내부 단편화 문제는 해결되어도 페이지 수가 많아지기 때문에 테이블의 크기가 커진다는 단점이 있다.



Segmentation

세그멘테이션 기법은 페이징 기법에서 나타나는 내부 단편화 문제를 해결하기 위해 고안된 방법으로

프로세스를 서로 다른 크기로 나누어 메모리에 할당하는 방법을 말한다.


이 때 나눈 부분을 세그멘테이션, 섹터라고 부른다.


세그멘테이션은 일반적으로 페이징 기법에 기반하여 사용되는데,

스택과 힙, 함수와 같이 논리적인 부분만 같은 구역에 넣어주고 나머지 부분은 page로 나누어 메모리에 할당하는 식으로 많이 사용된다.


하지만 이 세그멘테이션 기법은 각각의 섹터에 대해 페이지 테이블이 존재하기 때문에 접근할 때 오버헤드가 발생하고

페이지가 너무 잘게 쪼개져 있어 할당하기가 힘든 external fragmentation(외부 단편화) 문제가 발생하게 된다.



다음과 같이 세 가지 메모리 관리 기법을 알아보았다.


메모리 관리는 운영체제에 있어서 정말 필수적이고도 중요하기 때문에 운영체제를 공부하는 사람이라면

적어도 위의 세 가지 방법은 꼭 숙지하고 있어야 하겠다.



+ Recent posts