개발자는 기록이 답이다

혼공 컴퓨터구조 + 운영체제 14. 가상메모리 본문

CS/운영체제

혼공 컴퓨터구조 + 운영체제 14. 가상메모리

slow-walker 2024. 2. 11. 23:19

 

1. 연속 메모리 할당

 

지금까지는 메모리 내에 프로세스들이 연속적으로 배치되는 상황을 가정했다. 즉, 아래 그림과 같이 프로세스 A는 A의 크기만큼 메모리 주소를 할당받아 연속적으로 배치되고, 프로세스 B는 프로세스A 이후에 또 B의 크기만큼 연속적인 메모리 주소를 할당받아 배치되는 식이다.

 


이렇게 프로세스에 연속적인 메모리 공간을 할당하는 방식을 연속 메모리 할당 방식이라고 한다. 

이처럼 프로세스들을 메모리에 연속적으로 할당할 때 무엇을 고려해야 하는지, 그리고 어떤 잠재적인 문제가 있는지 알아보자.

 

스와핑

 

메모리에 적재된 프로세스들 중에는 현재 실행되지 않는 프로세스가 있을 수 있다.

  • 입출력 작업의 요구로 대기 상태가 된 프로세스
  • 오랫동안 사용되지 않은 프로세스가 이런 프로세스

 

이러한 프로세스들을 임시로 보조기억장치 일부 영역으로 쫓아내고,

그렇게 해서 생긴 메모리상의 빈 공간에 또 다른 프로세스를 적재하여 실행하는 방식 스와핑(swapping)이라고 한다.

 

  • 스왑영역(swap space)  : 프로세스들이 쫓겨나는 보조기억장치의 일부 영역
  • 스왑아웃(swap-out) :  현재 실행되지 않는 프로세스가 메모리에서 스왑 영역으로 옮겨지는 것
  • 스왑인(swap-in) : 스왑 영역에 있던 프로세스가 다시 메모리로 옮겨오는 것

 

스왑 아웃 되었던 프로세스가 다시 스왑 인될 때는 스왑 아웃되기 전의 물리 주소와는 다른 주소에 적재될 수 있다.

 

스와핑을 이용하면 프로세스들이 요구하는 메모리 주소 공간의 크기가 실제 메모리 크기보다 큰 경우에도 프로세스들을 동시 실행할 수 있다.

 

프로세스 A, B, C, D의 크기를 합하면 메모리의 크기보다 크지만, 스와핑을 통해 4개의 프로세스를 동시에 실행할 수 있다.

 

스왑 영역 확인하기

 

유닉스와 리눅스, Mac OS에서는 free, top명령어 등을 통해 스왑 영역의 크기를 확인할 수 있다.

스왑 영역의 킉와 사용 여부는 사용자가 임의로 설정할 수 있다.

 

메모리 할당


프로세스는 메모리 내의 빈 공간에 적재되어야 한다.

메모리 내에 빈 공간이 여러 개 있다면 프로 세스를 어디에 배치해야 할까?

 

비어 있는 메모리 공간에 프로세스를 연속적으로 할당하는 방식을 알아보자.


대표적으로 최초 적합, 최적 적합, 최악 적합의 세 가지 방식이 있다. 

 

▶ 예를 들어, 20MB 크기의 프로세스를 적재하고 싶다고 해보자.

메모리의 사용자 영역은 총 200MB라고 가정하면, 프로세스를 적재할 수 있는 빈 공간은 빈 공간 A, 빈 공간 B, 빈 공간 C 세 군데가 있다

 

 

최초 적합
  • 최초 적합(first fit) : 운영체제가 메모리 내의 빈 공간을 순서대로 검색하다가 적재할 수 있는 공간을 발견하면 그 공간에 프로세스를 배치하는 방식

 

즉, 운영체제가 빈 공간 A → 빈 공간 B → 빈 공 간 순으로 빈 공간을 검색했다면 프로세스는 빈 공간 A에 적재된다.

최초 적합 방식은 프로세스가 적재될 수 있는 공간을 발견하는 즉시 메모리를 할당하는 방식이므로 검색을 최소화할 수 있고 결과적으로 빠른 할당이 가능하다.

 

최적 적합

 

  • 최적 적합(best fit) : 운영체제가 빈 공간을 모두 검색해 본 후, 프로세스가 적재될 수 있는 공간 중 가장 작은 공간에 프로세스를 배치하는 방식

프로세스가 적재될 수 있는 빈 공간 중 가장 작은 공간은 빈 공간 C이다. 그렇게 최적 적합 방식으로 메모리를 할당하면 프로세스는 프로세스 C에 할당된다.

 

최악 적합

 

  • 최악 적합(worst fit) : 운영체제가 빈 공간을 모두 검색해 본 후, 프로세스가 적재될 수 있는 공간 중 가장 큰 공간에 프로세스를 배치하는 방식

 

프로세스가 적재될 수 있는 빈 공간 중 가장 큰 공간으 B이다. 그래서 최악 적합 방식으로 메모리를 할당하면 프로세스는 빈 공간B에 할당된다.

 

외부 단편화

 

프로세스를 메모리에 연속적으로 배치하는 연속 메모리 할당은 언뜻 들으면 당연하게 느껴질 수 있지만, 사실 메모리를 효율적으로 사용하는 방법이 아니다. 왜냐하면 연속 메모리 할당은 외부 단편화(external fragmentation)이라는 문제를 내포하고 있다. 외부단편화가 무엇이며 왜 발생하는지 알아보자.

 

외부 단편화 : 프로세스를 할당하기 어려울 만큼 작은 메모리 공간들로 인해 메모리가 낭비되는 현상

 

▶ 1. 아무런 프로세스도 적재되지 않은 상태

 

운영체제 영역에는 운영체제가 적재되어있고, 사용자 영역에는 어떠한 프로세스도 적재되어 있지 않다.

 

▶ 2. 사용자 영역에 하나둘씩 프로세스들이 적재되는 상황

  • 사용자 영역의 크기를 200MB라고 가정
  • 사용자 영역 크기가 50MB인 프로세스 A
  • 30MB인 프로세스 B
  • 100MB인 프로세스 C
  • 20MB인 프로세스 D

를 차례대로 메모리에 적재한다면 어떻게 배치되는게 좋을까?

 

▶ 3. 프로세스 B와 D의 실행이 끝난다고 가정

 

더 이상 메모리에 남아있을 필요가 없다. 프로세스 B와 D가 메모리를 떠나면 그 자리에 빈 공간이 생긴다.

 

  • 현재 메모리에 남아 있는 빈 공간의 총합 : 50MB

그렇다면 위 그림과 같은 상황에서 50MB 크기의 프로세스를 적재할 수 있을까? NO

 

빈 공간의 총합이 50MB일지라도 어느 빈 공간에도 50MB크기의 프로세스가 적재될 수 없기 때문이다.

프로세스들이 메모리에 연속적으로 할당되는 한경에서는 위와 같이 프로세스들이 실행되고 종료되기를 반복하며 메모리 사이 사이에 빈 공간들이 생긴다. 프로세스 바깥에 생기는 이러한 빈 공간들은 분명 빈 공간이지만 그 공간보다 큰 프로세스를 적재하기 어려운 상황을 초래하고, 결국 메모리 낭비로 이어어진다. 이러한 현상을 외부 단편화 라고 한다.

 

 

앞에서 설명했던 스와핑과 메모리 할당 예시에서도 외부 단편화는 발생했다.

왼쪽 그림을 보면 프로세스B가 스왑 아웃되고 프로세스 B보다 작은 프로세스 D가 적재되었을때 외부 단편화가 발생하는 것을 볼 수 있다.

외부 단편화 예시인 오른쪽 그림에서도 '적재할 프로세스' 바로 아래에 작은 빈 공간이 생겼는데, 이것 또한 외부 단편화가 발생한 예시이다.

 

 

앞 예시들에서는 메모리에 프로세스가 몇 개 없는 간단한 상황을 가정했기에 외부 단편화가 큰 문제가 아닌 것처럼 보일 수 있지만, 실제로는 이보다 메모리 용량도 크고 적재되는 프로세스도 많기 때문에 외부 단편화로 인해 낭비되는 공간은 더욱 크다.

그렇기에 외부 단편화 문제는 반드시 해결해야 할 문제이다.

 

외부 단편화를 해결할 수 있는 대표적인 방안으로 메모리를 압축(compaction)하는 방법이 있다.(메모리 조각 모음)

 

압축이란?

  • 여기저기 흩어져 있는 빈 공간들을 하나로 모으는 방식
  • 메모리 내에 저장된 프로세스를 적당히 재배치시켜 여기저기 흩어져 있는 작은 빈 공간들을 하나의 큰 빈 공간으로 만드는 방법

 

압축의 단점

  • 작은 빈 공간들을 하나로 모으는 동안 시스템은 하던 일을 중지해야 한다.
  • 메모리에 있는 내용을 옮기는 작업은 많은 오버헤드를 야기하며, 어떤 프로세스를 어떻게 움직여야 오버헤드를 최소화하며 압축할 수 있는지에 대한 명확한 방법을 결정하기 어렵다.

 

이에 외부 단편화를 없앨 수 있는 또 다른 해결 방안이 등장했는데, 이것이 오늘날까지도 사용되는 가상 메모리 기법, 그중에서도 페이징 기법이다.

 

2. 페이징을 통한 가상 메모리 관리

 

프로세스를 메모리에 연속적으로 할당하는 방식의 문제점

  • 외부단편화
  • 물리 메모리보다 큰 프로세스를 실행할 수 없다

 

프로세스를 반드시 메모리에 연속적으로 할당해야 한다면 메모리보다 큰 프로그램은 적재할 수 없다.

e.g. 4GB메모리가 설치된 컴퓨터로는 4GB이상의 프로그램을 실행할 수 없다.

 

가상메모리(Virtual memory)는 실행하고자 하는 프로그램을 일부만 메모리에 적재하여 실제 물리 메모리 크기보다 더 큰 프로세스를 실행할 수 있게하는 기술이다. 이를 가능케 하는 가상 메모리 관리 기법에는 크게 페이징세그멘테이션이 있지만. 이 책에서는 현대 대부분의 운영체제가 사용할 수 있는 페이징 기법을 다룬다. 페이징 기법을 이용하면 물리 메모리보다 큰 프로세스를 실행할 수 있을 뿐만 아니라 외부 단편화 문제도 해결 가능하다.

 

페이징이란

 

연속 메모리 할당 방식에서 외부 단편화가 생긴 근본적인 이유는 각기 다른 크기의 프로세스가 메모리에 연속적으로 할당되었기 때문이다.

 

만일 메모리와 프로세스를 일정한 단위로 자르고, 이를 메모리에 부연속적으로 할당할 수 있다면 외부 단편환느 발생하지 않는다.

예를 들, 위 그림에서 메모리 공간과 프로세스들을 10MB단위로 일정한 크기로 자르고, 잘린 메모리 조각들에 프로세스 조각들을 불연속적으로 적재할 수 있다면 아래 그림과 같이 외부 단편화는 발생하지 않는다.

 

이것이 페이징(paging)이다. 페이징은 프로세스의 논리 주소 공간인 페이지(page)라는 일정한 단위로 자르고, 메모리 물리 주소 공간을 프레임(frame)이라는 페이지와 동일한 크기의 일정한 단위로 자른 뒤 페이지를 프레임에 할당하는 가상 메모리 관리 기법이다.

 

페이징이란?

  • 메모리의 물리 주소 공간을 프레임 단위로 자르고, 프로세스의 논리 주소 공간을페이지 단위로 자른 뒤 각 페이지를 프레임에 할당하는 가상 메모리 관리기법

 

페이징에서도 스와핑을 사용할 수 있다.

페이징을 사용하는 시스템에서는 프로세스 전체가 스왑 아웃/ 스왑 인되는 것이 아닌 페이지 단위로 스왑 아웃/스왑인이 된다.

즉, 메모리에 적재될 필요가 없는 페이지들은 보조기억장치로 스왑 아웃되고, 실행에 필요한 페이지들은 메모리로 스왑 인되는 것이다.

  • 페이지 아웃(page-out)
  • 페이지 인(page-in)

 

한 프로세스를 실행하기 위해 프로세스 전체가 메모리에 적재될 필요가 없다는 말과 같다.

프로세스를 이루는 페이지 중 실행에 필요한 일부 페이지만을 메모리에 적재하고, 당장 실행에 필요하지 않은 페이지들은 보조기억장치에 남겨둘 수 있다. 이와 같은 방식을 통해 물리 메모리보다 더 큰 프로세스를 실행할 수 있다.