[CS 기초 - 운영체제] 메모리 관리 전략

deannn.Park·2021년 5월 15일
0

CS 기초

목록 보기
4/17
post-thumbnail

메모리 관리 전략


메모리 관리 배경

각각의 프로세스는 독립된 메모리 공간을 갖고, 운영체제 혹은 다른 프로세스의 메모리 공간에 접근할 수 없는 제한이 걸려있다. 단지, 운영체제만이 운영체제 메모리 영역과 사용자 메모리 영역의 접근에 제약을 받지 않는다.

Swapping

메모리의 관리를 위해 사용되는 기법. 표준 Swapping 방식으로는 Round Robin과 같은 스케줄링의 다중 프로그래밍 환경에서 CPU 할당 시간이 끝난 프로세스의 메모리를 보조 기억장치(e.g. 하드디스크)로 내보내고 다른 프로세스에 메모리를 할당할 수 있다.

위와 같은 과정을 Swap (스왑시킨다) 이라 한다. 주기억장치(RAM)으로 불러오는 과정을 Swap in, 보조기억장치로 내보내는 과정을 Swap out이라 한다. Swap에는 큰 디스크 전송시간이 필요하기 때문에 현재에는 메모리 공간이 부족할 때 Swapping 이 시작된다.

단편화 (Fragmentation)

프로세스들이 메모리에 적재되고 제거되는 일이 반복되다보면 프로세스들이 차지하는 메모리 틈 사이에 사용하지 못할 만큼의 작은 자유공간들이 늘어가게 되는데, 이것이 단편화이다. 단편화는 2가지 종류로 나뉜다.

Process AfreeProcess BfreeProcess C        free       Process D
  • 외부 단편화
    메모리 공간 중 사용하지 못하게 되는 일부분. 물리 메모리(RAM)에서 사이사이 남는 공간들을 모두 합치면 충분히 공간이 되는 부분들이 분상되어 있을 때 발생한다고 볼 수 있다.
  • 내부 단편화
    프로세스가 사용하는 메모리 공간에 포함된 남는 부분. 예를 들어 메모리 분할 자유 공간이 10,000B 있고 Process A가 9,998B 사용하게 되면 2B 라는 차이가 존재하고, 이를 내부 단편화라 칭한다.

압축

외부 단편화를 해소하기 위해 프로세스가 사용하는 공간들을 한쪽으로 몰아 자유공간을 확보하는 방법론. 작업 효율이 좋진 않다. 위의 메모리 현황을 압축 작업을 하게 된다면 아래와 같이 바뀐다.

Process AProcess BProcess C Process D                    free                    

 

Paging (페이징)

하나의 프로세스가 사용하는 메모리 공간이 연속적이어야 한다는 제약을 없애는 메모리 관리 방법이다. 외부 단편화와 압축 작업을 해소하기 위해 생긴 방법론으로, 물리 메모리는 Frame이라는 고정 크기로 분리되어 있고, 논리 메모리(프로세스가 점유하는)는 페이지라 불리는 고정 크기의 블록으로 분리된다. (페이지 교체 알고리즘에 들어가는 페이지)

페이징 기법을 사용함으로써 논리 메모리는 물리 메모리에 저장될 때, 연속되어 저장될 필요가 없고 물리 메모리의 남는 프레임에 적절히 배치됨으로 외부 단편화를 해결할 수 있는 큰 장점이 있다.

하나의 프로세스가 사용하는 공간은 여러개의 페이지로 나뉘어서 관리되고(논리 메모리에서), 개별 페이지는 순서에 상관없이 물리 메모리에 있는 프레임에 mapping되어 저장된다고 볼 수 있다.

단점

내부 단편화의 문제의 비중이 늘어난다. 예를 들어 페이지 크기가 1,024B이고 Process A가 3,172B의 메모리를 요구한다면 3개의 페이지 프레임(1,024 * 3 = 3,072)하고도 100B가 더 필요하기에 총 4개의 페이지 프레임이 필요한 것이다. 결론적으로 4번쩨 페이지 프레임에는 924B(1,024 - 100)의 여유공간이 남게 되는 내부 단편화 문제가 발생한다.

Segmentation (세그멘테이션)

페이징에서처럼 논리메모리와 물리메모리를 같은 크기의 블록이 아닌 서로 다른 크기의 논리적 단위인 세그먼트(Segment)로 분할. 사용자가 두 개의 주소고 지정(세그먼트 번호 + 변위). 세그먼트 테이블에는 각 세그먼트의 기준(세그먼트의 시작 물리주소)와 한계(세그먼트의 길이)를 저장.

단점

서로 다른 크기의 세그먼트들이 메모리에 적재되고 제거되는 일이 반복되다보면, 자유 공간들이 많은 수의 작은 조각들로 나누어져 못쓰게 될 수 있다. (외부 단편화)

 

가상 메모리


다중 프로그래밍을 실현하기 위해서는 많은 프로세스들을 동시에 메모리에 올려두어야 한다. 가상메모리는 프로세스 전체가 메모리 내에 올라오지 않더라고 실행이 가능하도록 하는 기법이며, 프로그램이 물리 메모리보다 커도 된다는 주요 장점이 있다.

가상 메모리 개발 배경

실행되는 코드의 전부를 물리 메모리에 존재시켜야 했고, 메모리 용량보다 큰 프로그램은 실행시킬 수 없었다. 또한, 여러 프로그램을 동시에 메모리에 올리기에는 용량의 한계와 페이지 교체 등의 성능 이슈가 발생하게 된다. 또한, 가끔만 사용되는 코드가 차지하는 메모리들을 확인할 수 있다는 점에서, 불필요하게 전체의 프로그램이 메모리에 올라와 있어야 하는 게 아니라는 것을 알 수 있다.

프로그램의 일부분만 메모리에 올릴 수 있다면...

  • 물리 메모리 크기에 제약받지 않게 된다.
  • 더 많은 프로그램을 동시에 실행할 수 있게 된다. 이에 따라 응답시간은 유지되고, CPU 이용률처리율은 높아진다.
  • swap에 필요한 입출력이 줄어들기 때문에 프로그램들이 빠르게 실행된다.

가상 메모리의 역할

가상 메모리는 실제의 물리 메모리 개념과 사용자의 논리 메모리 개념을 분리한 것이라 정리할 수 있다. 이로써 작은 메모리를 가지고도 얼마든지 큰 가상 메모리 공간을 프로그래머에게 제공할 수 있다.

가상 주소 공간

  • 한 프로세스가 메모리에 저장되는 논리적인 모습을 가상메모리에 구현한 공간이다. 프로세스가 요구하는 메모리 공간을 가상메모리에서 제공함으로써 현재 직접적으로 필요치 않은 메모리 공간은 실제 메모리에 올리지 않는 것으로 물리 메모리를 정햑할 수 있다.
  • 예를 등어, 한 프로그램이 실행되며 논리 메모리로 100KB가 요구되었다며 하자. 하지만 실행까지의 필요한 메모리 공간(Heap 영역, Stack 영역, 코드, 데이터)의 합이 40KB라면, 실제 메모리에는 40KB만 올라가 있고, 나머지 60KB 만큼은 필요시에 물리 메모리에 요구한다고 이해할 수 있다.

프로세스간의 페이지 공유

  • 가상메모리는 시스템 라이브러리가 여러 프로세스들 사이에 공유될 수 있도록 한다. 각 프로세스들은 공유 라이브러리를 자신의 주소 공간에 두고 사용하는 것처럼 인식하지만, 라이브러리가 올라가 있는 물리 메모리 페이지들은 모든 프로세스에 공유되고 있다.
  • 가상메모리는 프로세스들이 메모리를 공유하는 것을 가능하게 하고, 프로세스들은 공유 메모리로 통해 통신할 수 있다. 이 또한, 각 프로세스들은 각자 자신의 주소 공간처럼 인식하지만, 실제 물리 메모리는 공유되고 있다.
  • 가상메모리는 fork()를 통한 프로세스 생성 과정에서 페이지들이 공유되는 것을 가능하게 한다.

Demand Paging (요구 페이징)

프로그램 실행 시작 시에 프로그램 전체를 디스크에서 물리 메모리에 적재하는 대신, 초기에 필요한 것들만 적재하는 전략을 요구 페이징이라 하며, 가상 메모리 시스템에서 많이 사용된다. 그리고 가상 메모리는 대게 페이지로 관리된다. 요구 페이징을 사용하는 가상 메모리에서는 실행과정에서 필요해질 때 페이지들이 적재된다. 한 번도 접근되지 않은 페이지는 물리 메모리에 적재되지 않는다.

프로세스 내 개별 페이지들은 페이저(pager)에 의해 관리된다. 페이저는 프로세스 실행에 실제 필요한 페이지들만 메모리에 읽어 옴으로써, 사용되지 않을 페이지를 가져오는 시간 낭비와 메모리 낭비를 줄일 수 있다.

페이지 교체

요구 페이징에서 언급된대로 프로그램 실행시에 모든 항목이 물리 메모리에 올라오지 않기 때문에, 프로세스의 동작에 필요한 페이지를 요청하는 과정에서 apge fault(페이지 부재)가 발생하게 되면, 원하는 페이지를 보조저장장치에서 가져오게 된다. 하지만, 만약 물리 메모리가 모두 사용중인 상황이라면, 페이지 교체가 이뤄줘야 한다. (또는 운영체제가 프로세스를 강제 종료하는 방법이 있다.)

기본적인 방법

물리 메모리가 모두 사용중이 상황에서의 메모리 교체 흐름이다.

  1. 디스크에서 필요한 페이지의 위치를 찾는다.
  2. 빈 페이지 프레임을 찾는다.
    i. 페이지 교체 알고리즘을 통해 희생될(victim)페이지를 고른다.
    ii. 희생될 페이지를 디스크에 기록하고, 관련된 테이블을 수정한다.
  3. 새롭게 비워진 페이지 테이블 내 프레임에 새 페이지를 읽어오고, 프레임 테이블을 수정한다.
  4. 사용자 프로세스 재시작

페이지 교체 알고리즘

1. FIFO 페이지 교체

가장 간단한 페이지 교체 알고리즘으로, FIFO(First In First Out)의 흐름을 가진다. 즉, 먼저 물리 메모리에 들어온 순서대로 페이지 교체 시점에 먼저 나가게 된다는 것이다.

  • 장점
    • 이해하기 쉽고, 프로그램하기도 쉽다.
  • 단점
    • 오래된 페이지가 항상 불필요하지 않은 정보를 포함하지 않을 수 있다. (초기 변수 등)
    • 처음부터 활발하게 사용되는 페이지를 교체해서 페이지 내 부재율을 높이는 부작용을 초래할 수 있다.
    • Belady의 모순: 페이지를 저장할 수 있는 페이지 프레임의 갯수를 늘려도 되려 페이지 부재가 더 많이 발생하는 모순이 존재한다.

2. 최적 페이지 교체 (Optimal Page Replacement)

Belady의 모순을 확인한 이후 최적 교체 알고리즘에 대한 탐구가 진행되었고, 모든 알고리즘보다 낮은 부재율을 보이며 Belady의 모순이 발생하지 않는다. 이 알고리즘의 핵심은 앞으로 가장 오랫동안 사용되지 않을 페이지를 찾아 교체하는 것이다. 주로 비교 연구 목적을 위해 사용한다.

  • 장점
    • 알고리즘 중 가장 낮은 페이지 부재율을 보장한다.
  • 단점
    • 구현의 어려움이 있다. 모든 프로세스의 메모리 참조의 계획을 미리 파악할 방법이 없기 때문이다.

3. LRU 페이지 교체 (LRU Page Replacement)

LRU: Least Replacemently Used
최적 알고리즘의 근사 알고리즘으로, 가장 오랫동안 사용되지 않은 페이지를 선택하여 교체한다.

  • 특징
    • 대체적으로 FIFO 알고리즘보다 우수하고, OPT(최적) 알고리즘보다는 그렇지 못한 모습을 보인다.

4. LFU 페이지 교체 (LFU Page Replacement)

LFU: Least Frequently Used
참조 횟수가 가장 적은 페이지를 교체하는 방법이다. 활발하게 사용되는 페이지는 참조 횟수가 많아질 것이라는 가정에서 만들어진 알고리즘이다.

  • 특징
    • 최적(OPT) 페이지 교체를 제대로 근사하지 못하기 때문에 잘 쓰이지 않는다.
    • 어떤 프로세스가 특정 페이지를 집중적으로 사용하다 다른 기능을 사용하게 되면, 더 이상 사용하지 않아도 계속 메모리에 머물게 되어 초기 가정에 어긋나는 시점이 발생할 수 있다.

5. MFU 페이지 교체

MFU: Most Frequently Used
참조 횟수가 가장 적은 페이지가 최근에 메모리에 올라왔고, 앞으로 계속 사용될 것이라는 가정에 기반한다.

  • 특징
    • 최적(OPT) 페이지 교체를 제대로 근사하지 못하기 때문에 잘 쓰이지 않는다.

 

캐시의 지역성


캐시의 지역성 원리

캐시 메모리는 속도가 빠른 장치와 느린 장치간의 속도차에 따른 병목 현상을 줄이기 위한 범용 메모리이다. 이러한 역할을 수행하기 위해서는 CPU가 어떤 데이터를 원하는지를 어느정도 예측할 수 있어야 한다. 캐시의 성능은 작은 용량의 캐시메모리에 CPU가 이후에 참조할, 쓸모있는 정보가 어느정도 등러있느냐에 따라 좌우되기 때문이다.

이 때 적중률(Hit rate)을 극대화시키기 위해 데이터 지역성(Locality)의 원리를 사용한다. 지역성의 전제 조건으로 프로그램은 모든 코드나 데이터를 균등하게 Access하지 않는다는 특성을 기본으로 한다. 즉, Locality란, 기억장치 내의 정보를 균일하게 Access하는 것이 아닌 어느 한 순간에 특정 부분을 집중적으로 참조하는 특성인 것이다.
이 데이터 지역성은 대표적으로 시간 지역성(Temporal Locality)과 공간 지역성(Spatial Locality)으로 나뉜다.

  • 시간 지역성: 최근에 참조된 주소의 내용은 곧 다음에 다시 참조되는 특성
  • 공간 지역성: 대부분의 실제 프로그램이 참조된 주소와 인접한 주소의 내용이 다시 참조되는 특성

Caching line

언급했듯이 캐시(cache)는 프로세서 가까이에 위치하면서 빈번하게 사용되는 데이터를 놔두는 장소이다. 하지만 캐시가 아무리 가까이 있더라고 찾고자 하는 데이터가 어느 곳에 저장되어 있는지 몰라 모든 데이터를 순회해야 한다면 시간이 오래 걸리게 된다. 즉, 캐시에 목적 데이터가 저장되어 있다면 바로 접근하여 출력할 수 있어야 캐시가 의미 있어진다는 것이다.

그렇기 때문에 캐시에 데이터를 저장할 때에는 특정 자료구조를 사용하여묶음으로 저장하게 되는데, 이를 캐싱 라인이라고 한다. 프로세스는 가양한 주소에 있는 데이터를 사용하므로 빈번하게 사용하는 데이터의 주소 또한 흩어져 있다. 따라서 캐시에 저장하는 데이터는 데이터의 메모리 주소 등을 기록해 둔 태그를 달아놓을 필요가 있다. 이러한 태그들의 묶음을 캐싱 라인이라고 하고 메모리로부터 가져올 때에도 캐실 라인을 기준으로 가져온다. 종류로는 대표적으로 세 가지 방식이 존재한다.

  1. Full Associative
  2. Set Associative
  3. Direct Map

참고
한재엽님 Github - 운영체제
https://github.com/gyoogle/tech-interview-for-developer/blob/master/Computer%20Science/Operating%20System/Paging%20and%20Segmentation.md

profile
컴퓨터 관련 여러 분야 공부중

0개의 댓글