Article/OS - Deep Dive

메모리 단편화와 페이징

조금씩 차근차근 2025. 4. 14. 22:50

메모리 단편화를 해결하는 방법, 페이징에 대해 알아보자.

페이징

페이징이란, 가상 메모리 공간의 메모리 관리 기법을 의미한다.

페이징의 설계 방식

  • 메모리를 페이지 단위로 잘라서 사용한다.
    • 물리 메모리의 크기 단위를 프레임이라고 할 때, 가상 메모리를 위한 "페이지"라는 단위를 만들어
    • 하나의 페이지를 하나의 프레임과 1:1 크기로 매핑하는 것을 의미한다.
  • 프로세스는 자신이 할당받은 가상 주소 공간 내에서, 가상 메모리를 페이지 단위로 사용하게 된다.
  • 가상 주소 공간 관리 기법이다.
  • 페이징 자체에 가상 주소 공간 개념이 포함된다. 고정된 메모리 풀 할당 방식과 혼동하지 말자.

페이징의 효과

  • 물리 메모리의 외부 단편화 문제를 해결한다.
    • 프로세스가 사용하는 메모리 계층과 할당되는 물리 메모리 계층을 분리한다.
  • 페이지의 크기가 줄어들수록, 내부 단편화 문제를 줄인다.
    • 그 대신, 페이지 크기가 줄어들수록, 페이지 테이블에 저장해야 할 엔트리의 수가 많아짐을 생각하자.

지금부터 페이징이 어떻게 외부 단편화 문제를 해결하는지 알아보자.

가상 메모리

  • 운영체제와 하드웨어 아키텍처에 의해 미리 정의된, 매우 넓은 주소 범위의 실제로 존재하지 않는 메모리를 의미한다.
    • 이때, 사용하지 않는 영역은 디스크에 보관할 수 있게 만든다.
    • 그리고 현재 사용하는 메모리만 물리 메모리에 올릴 수 있도록 만든다.

가상 주소 공간

  • 프로세스 별로 할당되는 주소 공간을 의미한다.
    • 0xFFFFFF 와 같은
  • 실제 물리 메모리보다 훨씬 큰 주소 공간을 제공한다.

가상 메모리 단편화

지금까지 설명을 쭉 보면, 결국 어딘가에 연속 할당은 해야 한다.
단편화 문제는 결국 “연속된 메모리 할당” 을 선택하는 순간 항상 따라오게 될 문제같은데, 가상 메모리에서 연속할당을 하면, 가상 주소 테이블에서 또다시 외부 단편화가 발생할 것이라는 추측이 가능할 것이다.
그렇다면, 다음과 같은 의문이 발생한다.

  • 기존에 물리 주소 공간에서 발생한 단편화가 가상 주소 공간에서 그대로 발생할 것 같은데?
  • 그럼 페이징을 왜 쓰는거지?

페이징을 쓰는 이유

위 가상 메모리의 설명을 보면, “프로세스 별로 갖는”, “매우 넓은 주소 범위” 라는 특징을 갖는다는 것을 볼 수 있다.

일반적으로 가상 메모리는 32bit 운영체제의 경우 2^32 = 4GB까지 가질 수 있고, 64bit 운영체제의 경우 2^64 = 16EB까지 가질 수 있으며, 실제로는 프로세스 별로 128TB정도 할당을 받는다.

또한, 실제 가상 주소 공간 내 페이지가 실제로 접근(읽기/쓰기) 될 때 - page fault가 발생하면,

  • 아직 할당된적 없는 페이지이면, 페이지 폴트가 발생하며, 그 시점에 운영체제가 물리 메모리를 매핑(할당)해준다.
    • Anonymous mapping & demand paging
    • 정확히는, 프로세스 시작시에는 처음 접근되는 모든 페이지가 첫 접근 시 페이지 폴트를 발생시킨다.
  • 할당된 적 있는 페이지인데 디스크에 있으면, 페이지 폴트를 발생시킨다.
    • demand paging
  • 할당 해제(munmap)시, 해당 가상 주소 공간에 접근 시 page fault 가 발생하게 만든다.
    • 해당 프레임은 OS 레벨에서 해제되어서, 프레임 할당 풀로 돌아가게 된다.

따라서, 가상 메모리 단편화 문제는 64bit 운영체제에서는 (거의) 무한한 가상 메모리로 인해 발생하기 힘들다.

단, 32bit 운영체제에선 가상 메모리 크기가 4GB밖에 안돼서 가상 메모리의 외부 단편화가 발생할 수 있다.

페이징은 단점이 없나?

지금까지의 설명만 들어보면, 페이징은 완벽한 기술처럼 보인다. 하지만 여기엔 고려되지 않은 관점이 있다.

  • 내구성 소모 관점
    • 페이징의 구현 시 사용되는 demand paging과 같은 기술은 전력과 SSD 읽기/쓰기 횟수를 소모한다.
  • 메모리 용량 관점
    • 페이징은 외부 단편화 문제는 효과적으로 해결할 수 있지만, 여전히 내부 단편화 문제는 존재한다.
    • 이는 메모리 용량이 부족할 경우, 치명적으로 다가올 수 있다.

따라서 모바일 기기와 같은 실시간성이 중요하지 않으면서 유휴 시간을 갖는 기기의 경우에는, 페이징보단 메모리 압축을 사용하게 된다.

그렇다면 세그멘테이션은?

분명 어디선가, 세그멘테이션으로 내부 단편화 문제를 해결할 수 있다는 이야기를 들었을 것이다.
하지만 현대에는 쓰이지 않는다. 지금부터 그 이유를 알아보자.

세그멘테이션이란?

  • 프로세스를 통째로 연속적으로 저장하는것이 아닌
    • 코드, 데이터, BSS, 힙, 스택
      • 각 영역을 세그먼트라고 부른다.
    • 물리적으로 묶여야 하는 개념끼리만 연속해서 저장한다.

현대 64비트 운영체제에서는 잘 사용되지 않는 이유

  • 위에서 이야기한, 가상 주소 공간 단편화의 해결 덕분에, 세그멘테이션을 할 이유를 잃어버리게 되었다.
    • 매우 큰 가상 주소 공간 덕분에, 외부 단편화가 발생해도 애초에 문제가 되지 않는 설계가 되었다.
  • 따라서 교육/개념적인 목적으로만 남아있다.
    • 지긋지긋한 segementation fault
      출처: https://eng.libretexts.org/Bookshelves/Computer_Science/Programming_Languages/Introduction_To_MIPS_Assembly_Language_Programming_%28Kann%29/06%3A_MIPS_Memory_-_the_Data_Segment/6.01%3A_Flat_Memory_Model

 

 

페이징의 구현 방식 - 링크 참고(작성예정)