Computer Science/[ OS ]

[ OS ] 14. 메모리 관리 전략 - 연속 메모리 할당

kim.svadoz 2021. 6. 3. 17:54
반응형

연속 메모리 할당

Contiiguous Memory Allocation

메모리는 크게 운영체제를 위한 저장공간과, 사용자 프로세스들을 위한 공간 두 파티션으로 이루어져 있다.

운영체제는 인터럽트와 큰 상관관계가 있다. 사실 운영체제 데이터를 0번지 등의 메모리 하단에 위치시켜도 되고, 윗단에 위치시켜도 되는데, 보통은 밑단에 있다. 그 이유는 인터럽트 벡터가 주로 낮은 메모리에 위치되어 있다. 그래서 앞으로 운영체제는 메모리 주소 하단에 저장되어 있다 가정할 것이다.

  • MMU : CPU 코어 안에 탑재 되어서 가상 주소를 실제 메모리 주소로 변환 해주는 장치

기준점의 위치가 다르더라도 offset은 같기 때문에, 더하기를 통해서 물리적 주소도 논리적 주소처럼 연속적으로 배치되게 된다.

=> 이게 바로 연속적 메모리 할당 이라고 하는 contiguous allocation이다.

즉, `Contiguous allocation 연속 메모리 할당이란 "logical address가 연속적이면 physical address도 연속적으로 배치된다" 라는 것이다.

Memory Protection

운영체제에는 CPU 관리, 메모리 관리, I/O 관리의 세 가지 기능이 있다.

CPU 관리를 위해선 CPU Protection이,
메모리 관리를 위해선 Memory Protectioin이,
IO 관리를 위해선 I/O Protection이 있다.

만약 Memory Protection이 없다면 (가정) 실제 램 memory 주소는 1000까지이고 base memory가 400번지라고 해보자. 근데 offset이 700이다. 그러면 400 + 700 해서 1100으로 우리가 갖고 있는 실제 메모리 주소 크기보다 벗어나면 문제가 발생할 수 있다.

따라서 이렇게 잘못된 메모리 번지를 참조하지 않도록 막아주는 게 Memory Protection이다.

그러면 내가 참조할 수 있는 범위인지 아닌지 어떻게 체크할 수 있을까?

바로 limit register(상한 레지스터)가 추가 되었다. 상한 레지스터 보다 가상 주소 값이 크면 Memory Protection fault를 발생시킨다.

상한 값은 RAM 메모리 크기가 될 수도 있지만 현재는 그렇게 쓰이지 않는다. 멀티프로그래밍 시스템일 경우 각 프로세스들이 서로 메모리를 침범하면 안된다. 기본적으로 각각의 필요한 메모리를 보호해준다.

- memory protection fault란?

CPU 가 명령어를 수행하는데 이게 가상 주소가 1100000이었고, 얘가 참조할 수 있는 address는 100만 이었다고 합시다. 근데 얘가 110만번을 참조하고 그래요. 그러면 CPU는 이 명령어를 수행하면 안되지만 CPU가 하는 일은 CPU명령을 수행하는거지 판단을 하진 않는다.

그래서 실행을 하려 하는데 이게 참조하려는 메모리 크기보다 크니까 올바른 명령어가 아닐 때 운영체제에게 도움을 요청한다.

CPU가 자기 자신한테 인터럽트를 거는 것을 Exception 혹은 trap, fault이라고 한다.

fault는 조금 더 일반적인 명사를 의미하며 CPU가 자기 자신한테 인터럽트를 걸어서 이거는 내가 처리할 수 있는 명령어가 아니니, 운영체제보고 처리해달라고 요청을 하는 것이다.

Memory Allocatoin

Process가 실행되기 위해서는 Memory에 적재되어야 하고, 자신만의 space를 가져야 한다. 그럼 어떻게 memory를 더욱 효율적으로 사용할 수 있을까?

고정된 영역만 memory에 할당하는 static memory allocation과는 다르게 dynamic memory allocation은 프로세스가 돌아가는 runtime 내에 영역의 크기를 알려줌으로써 영역을 확보하는 방법이다.

프로세스가 실행되고 종료되면서 충분히 들어갈 여러 공간이 있을 때, 현재 프로세스가 어떤 공간에 들어가는게 효율적일까? 라고 고민에 대한 세 가지 전략이 있다.

  • Fisrt-Fit (최초 적합)
    • Linked List
    • 가장 최초로 발견되는 hole에 할당
    • 남은 메모리를 순차적으로 앞에서부터 탐색하는데, 이 프로세스가 들어갈 수 있는 hole중 최초에 발견된 hole에 배치
  • Best-Fit (최적 적합)
    • Priority Queue
    • 여기다 넣을지 저기다 넣을지 다 한번씩 대보는 것이다.
    • 어차피 공간에 자투리이 생기긴 하지만, 가장 작은 자투리가 생기는 hole에 배치
  • Worst-Fit (최악 적합)
    • Priority Queue
    • 가장 큰 공간, 즉 가장 남는 공간에다가 배치
    • 왜 이런 생각을 했을까? -> 자투리를 크게 만들어야 다른 프로세스가 거기 들어갈 확률이 있는 것 아니냐

Dynamic Memory Allocation은어떤 Fit을 쓰건 결국 Externel Fragmentation(외부 단편화) 문제를 일으킨다.

  • 장점
    • 더하기 하나만 하면 되니까 MMU가 매우 간단하다.
    • memory protectoin fault 체크 할 때 '이 값이 어떤 값보다 넘어섰냐 아니냐'만 체크하면 된다.
    • 즉, 하드웨어 만들기가 매우 쉽다.
    • 하지만, 안쓰이는 데는 이유가 있는법?!

External Fragmentation

조각, 단편화

연속 메모리 할당은 MMU가 간단해지지만, 안쓰는 이유가 무엇인가. 그에 대해 알아본다.

프로세스들이 연속적으로 배치되고, 실행 후 종료가 되면 그 사이 사이에 공간(Hole)이 생긴다.

External Fragmentation이란 총 공간을 계산해 봤을 때 요청알 만족할만한 충분한 메모리가 있음에도 불구하고, 가능한 공간들이 연속적이지 않아 발생하는 문제이다.
(즉, 저장공간들이 많고 작은 hole들로 조각조각 나 있을 때)

image-20210516141544430

이해를 위한 그림으로 여기서 프로세스 1과 5가 종료되어 메모리 공간이 있음에도 불구하고 실제로 할당할 수 없는 문제가 발생한다.

메모리는 엄청나게 비싼 자원인데 이런 문제로 메모리가 낭비되는것이다.

뭐 예를들어 남은 프로세스들을 한쪽으로 쭉 밀면 메모리 공간이 발생하게 되지만, secondary stroage인 하드디스크에다가 임시로 복사하고 저장하고, 하는 과정은 효율적이지 못해 실효성이 없는 방법이다.

이렇게 비어있는 공간을 연속적인 공간으로 만들고 움직이는 작업을 compaction이라고 한다.

이 방법은 external fragmentation을 줄일 수 있는 방법이긴 하지만, 메모리를 copy는 과정에서 반드시 I/O Problem을 일으키게 되므로 좋은 방법이 되지 않는다.

지금까지 배운방법은 프로세스 크기 별로 메모리를 할당하는데, 이를 가변 분할 이라고 한다. (모든 프로세스 크기는 다르니까)

그래서 메모리를 고정된 크기로 할당시키는 고정 분할 Paging이라는 기법을 배우게 된다. (여기서 내부 단편화가 발생한다)

반응형