# 메모리 관리

운영체제는 한정된 메모리를 극한으로 활용하기 위해 메모리 관리를 해야합니다.

# 가상 메모리(Virtual memory)

# 가상 메모리 등장 배경

  • 초창기 컴퓨터에서는 사용 가능한 RAM의 용량이, 가장 큰 실행 애플리케이션의 주소 공간보다 커야 했습니다. 그렇지 않은 경우 메모리 부족 오류에 의해 해당 애플리케이션을 실행할 수 없었습니다.
  • 애플리케이션의 일부분만 기억장치에 올려 실행하도록 하는 오버레이 기법을 사용하여 메모리 부족 문제를 해결하고자 했지만, 시스템이 프로그램을 위한 충분한 메모리를 갖추고 있지 않은 경우에는 메모리 부족 문제가 여전히 발생했습니다.
  • 애플리케이션을 실행하는데 얼마나 많은 메모리가 필요한지에 집중하지 않고, 애플리케이션을 실행하는 데 최소한 얼마만큼의 메모리가 필요한가에 집중하여 가상 메모리 기법을 만들어 냈습니다.
  • 메모리 접근은 순차적이고 지역화 되어 있기 때문에 이러한 접근 방식이 가능합니다.

TIP

애플리케이션의 실행에 필요한 일부분만 메모리에 올려지고, 메모리에 올라가지 않는 나머지는 디스크에 위치합니다. 즉, 디스크가 RAM의 보조 기억장치처럼 작동합니다.

# 가상 메모리란?

컴퓨터가 실제로 이용 가능한 메모리 자원을 추상화하여 이를 사용하는 사용자들에게 매우 큰 메모리로 보이게 만드는 것을 말합니다.

  • 가상적으로 주어진 주소를 가상 주소(logical address), 실제 메모리상에 있는 주소를 실제 주소(physical address)라고 합니다.
  • 가상 주소는 메모리관리장치(MMU)에 의해 실제 주소로 변환되며, 이에 따라 사용자는 실제 주소를 의식할 필요가 없어졌습니다.
  • 가상 메모리는 가상 주소와 실제 주소가 매핑되어 있고 프로세스의 주소 정보가 들어있는 '페이지 테이블'로 관리됩니다. 이때, 속도향상을 위해 TLB를 사용합니다.

TLB(Translation Lookaside Buffer)란?

메모리와 CPU 사이에 있는 주소 변환을 위한 캐시입니다. 페이지 테이블에 있는 리스트를 보관하며 CPU가 페이지 테이블까지 가지 않도록 해 속도를 향상시킬 수 있는 캐시 계층입니다.

# 스와핑(Swapping)

만약 가상 메모리에는 존재하지만 실제 메모리인 RAM에는 없는 데이터나 코드에 접근할 경우 페이지 폴트가 발생합니다. 이를 방지하기 위해 당장 사용하지 않는 영역을 하드디스크로 옮겨 필요할 때 다시 RAM으로 불러와 올리고 사용하지 않으면 다시 하드디스크로 내림을 반복하며 RAM을 효과적으로 관리하는 것을 뜻합니다.

# 페이지 폴트(Page Fault)

프로세스의 주소 공간(가상 메모리)에는 존재하지만 컴퓨터의 RAM에는 없는 데이터에 접근했을 경우에 발생하는 현상을 의미합니다.

  • 페이지 폴트가 발생하면 운영체제는 그 데이터를 메모리로 가져와서, 페이지 폴트가 전혀 발생하지 않은 것처럼 프로그램이 계속 작동하게 해줍니다.
  • 페이지 폴트와 그로 인한 스와핑의 과정
    1. CPU는 물리 메모리를 확인하여 해당 페이지가 없으면 트랩을 발생해서 운영체제에 알립니다.
    2. 운영체제는 CPU의 동작을 잠시 멈춥니다.
    3. 운영체제는 페이지 테이블을 확인하여 가상 메모리에 페이지가 존재하는지 확인하고, 없으면 프로세스를 중단하고 현재 물리 메모리에 비어 있는 프레임이 있는지 찾습니다. 물리 메모리에도 없다면 스와핑이 발생합니다.
    4. 비어 있는 프레임에 해당 페이지를 로드하고, 페이지 테이블을 최신화합니다.
    5. 중단되었던 CPU를 다시 시작합니다.
  • 페이지 폴트가 자주 일어날수록 운영체제의 성능이 저하되기 때문에 '페이지 교체 알고리즘'을 통해 페이지 폴트가 일어나지 않도록 해줘야합니다.

용어

페이지(page)
: 가상 메모리를 사용하는 최소 크기 단위

프레임(frame)
: 실제 메모리를 사용하는 최소 크기 단위

# 스레싱(Thrashing)

여러 프로그램을 한 번에 실행하면 하드디스크와의 입출력이 계속되어 프로그램이 정지한 것 같은 현상이 발생할 수 있습니다. 메모리가 꽉 찬 이후 새로운 프로그램을 올리기 위해 기존 프로그램을 스왑 영역에 옮기는 횟수가 증가하기 때문입니다. 이처럼 하드디스크의 입출력이 너무 많아져 잦은 페이지 부재로 CPU 이용률이 급격히 저하되는 현상을 스레싱이라고 합니다.

  • 메모리의 페이지 폴트율이 높은 것을 의미하며, 이는 컴퓨터의 심각한 성능 저하를 초래합니다.
  • 메모리에 너무 많은 프로세스가 동시에 올라가게 되면 스와핑이 많이 발생합니다.
  • 페이지 폴트가 일어나면 CPU 이용률이 낮아지고, 그러면 운영체제는 CPU가 한가한 줄 알고 가용성을 높이기 위해 더 많은 프로세스를 메모리에 올립니다.
  • 이러한 악순환이 반복되며 스레싱이 발생하게 됩니다.
  • 프로세스에 너무 적은 프레임을 할당하면 페이지 부재가 자주 발생하고, 너무 많은 프레임을 할당하면 메모리가 낭비됩니다. 따라서 남아 있는 프레임을 실행 중인 프로세스에게 적절히 나누어 주는 정책이 필요합니다.
    • 정적할당(static allocation) : 프로세스 실행 초기에 프레임을 나누어준 후 그 크기를 고정하는 것
      • 균등 할당 방식(equal allocation)
      • 비례 할당 방식(proportional allocation)
    • 동적할당(dynamic allocation) : 프로세스 실행 상황을 고려하여 프레임을 할당하는 방식
      • 작업세트 (작업집합모델을 사용)
      • PFF (페이지 부재 빈도를 사용)

# 균등 할당 방식

프로세스의 크기에 상관없이 모든 프로세스들에게 동등하게 사용 가능한 프레임을 나누어주는 방식입니다. 전체적으로 보면 공평하다는 느낌을 줄 수 있지만, 페이지 부재가 빈번하게 발생할 가능성이 커지게 되는 단점이 발생합니다.

# 비례 할당 방식

프로세스의 크기에 비례하여 프레임을 할당하는 방식입니다. 비례 할당 방식보다는 괜찮지만, 프로세스가 실행 중에 필요로 하느 프레임을 유동적으로 반영하지 못한다는 단점과, 사용하지 않은 메모리를 처음부터 미리 확보하여 공간을 낭비한다는 단점을 가지고 있습니다.

# 작업세트(Working set)

가장 최근에 접근한 프레임이 이후에도 또 참조될 가능성이 높다는 지역성(locality)를 이용한 방식입니다. 프로세스의 과거 사용 이력인 지역성(locality)를 통해 결정된 페이지 집합을 만들어서 미리 메모리에 로드하는 것입니다. 미리 메모리에 로드하면 탐색에 드는 비용을 줄일 수 있고 스와핑 또한 줄일 수 있습니다.

# PFF(Page Fault Frequency)

페이지 부재 횟수를 기록하여 프로세스마다 페이지 부재 비율을 계산하는 것입니다. 페이지 폴트 빈도를 조절하는 방법으로 상한선과 하한선을 설정합니다. 만약 상한선에 도달한다면 페이지를 늘리고 하한선에 도달한다면 페이지를 줄이는 것입니다.

# 참고자료

  • 주홍철.면접을 위한 CS 전공지식 노트.서울:길벗,2022.
  • https://ahnanne.tistory.com/15
  • https://straw961030.tistory.com/155