운영체제 메모리

2025. 10. 14. 16:43·Android

공식문서에 따르면 안드로이드 플랫폼은 사용 가능한 메모리가 있다는 것은 메모리를 낭비라는 전제 하에 작동하기 때문에 항상 사용 가능한 모든 메모리를 사용하기 때문에 Android 기기는 사용 가능한 메모리가 거의 없는 상태로 실행되는 경우가 많습니다. 

 

ART(Android Run Time)과 Dalvik VM은 페이징(paging)과 메모리 매핑 기법을 사용해 메모리를 관리합니다. 이를 이해하기 위해선 프로세스가 메모리(RAM)에 할당되는 방식에 대해서 알아보겠습니다.

모든 실행되는 명령어와 데이터들은 CPU가 직접적으로 접근할 수 있는 메인 메모리와 레지스터에 있어야 합니다. 또한 각각의 프로세스는 독립된 메모리 공간을 가집니다. 이 공간은 일반적으로 다음과 같이 구분됩니다.

  • 코드 영역 (Text Segment): 프로그램의 실행 명령어(컴파일된 코드)가 저장되는 영역
  • 데이터 영역 (Data Segment): 전역 변수나 싱글턴, 정적 멤버처럼 프로그램 시작 시 할당되고 종료 시 해제되는 데이터저장
  • 힙 영역 (Heap): 실행 중 동적으로 할당되는 메모리가 저장되는 영역으로 GC(Garbage Collector)의 정리 대상.
  • 스택 영역 (Stack): 함수 호출 시 지역 변수, 매개변수, 반환 주소 등이 저장되는 영역, 함수 호출이 끝나면 자동으로 해제

프로세스가 메모리에 적재될 때 CPU와 데이터, 그리고 메모리 간의 관계는 다음 문장으로 요약할 수 있습니다.

메모리에는 데이터가 저장되고 이 데이터는 주소로 식별된다.

그리고 이 주소는 두 가지 관점으로 나누어집니다. 

  • 메모리 관점의 주소 (물리 주소, Physical Address) : 실제 메모리(RAM) 상에 저장되어 있는 주소 
  • CPU 관점의 주소 (논리 주소, Logical Address) : 각 프로세스와 CPU가 인식하는 주소

논리 주소는 실행 중에 물리 주소로 변환 되어야 하며 이 변환 작업은 메모리 관리 장치(MMU, Memory Management Unit)에 의해 수행됩니다. Android에서 사용하는 메모리 매핑(memory mapping) 기법이 바로 이 원리를 기반으로 합니다.

메모리 할당 정책(memory allocation policy)

운영체제(OS)는 프로세스가 실행될 때 주기억장치(Main Memory)에서 실행에 필요한 크기의 메모리를 할당해야 합니다. 초기 운영체제들은 연속 메모리 할당(Contiguous Memory Allocation)방식을 사용했습니다. 이는 하나의 프로세스에 필요한 메모리를 물리적으로 연속된 하나의 공간에 할당하는 방식으로, 예를 들어 50MB 프로세스는 50MB의 연속된 메모리 블록이 필요했습니다.

 

이때 어떤 위치에 얼마만큼의 메모리를 줄 것인지 결정하는 것을 메모리 할당 정책이라 합니다. 프로세스가 종료되면 OS는  메모리를 반납하여 다른 프로세스가 사용할 수 있도록 합니다.  

프로세스를 메모리에 할당할 때는 다음과 같은 기법을 사용합니다.

  • 최초 적합(First Fit)
    • 메모리 공간을 순차적으로 탐색하다 사용 가능한 공간을 만나면 즉시 할당
  • 최적 적합(Best Fit)
    • 사용 가능한 공간 중 가장 작은 곳에 할당
    • 메모리가 크기 순으로 정렬 되어있지 않다면 전체 공간 탐색
  • 최악 적합(Worst Fit)
    • 사용 가능한 공간 중 가장 큰 곳에 할당
    • 프로세스를 할당하고 남은 공간은 다른 프로세스가 할당될 수 있도록 분리
    • 메모리가 크기 순으로 정렬되어있지 않다면 전체 공간을 탐색

외부 단편화(external fragmentation)

최초/최적 기법을 사용해 프로세스들이 메모리를 할당/해제하는 과정이 반복되면 메모리 내에는 사용 중인 영역과 비어 있는 영역(hole)이 불규칙하게 섞이게 됩니다. 이로 인해 메모리의 여유 공간이 충분함에도 공간이 부족하여 새 프로세스를 배치할 수 없는 상황이 발생하는데, 이를 외부 단편화라고 합니다.

 

예컨대 50MB의 프로세스를 메모리에 등록해야 할 때 현재 메모리에 남아있는 공간의 총합이 50MB임에도 hole이 나누어져 있어 프로세스를 적재할 수 없는 문제가 발생합니다.

이로 인해 메모리를 할당할 때 어떤 전략을 사용할 것인지는 단편화의 크기에 영향을 받으며 시스템에 따라 때론 최초 적합이 적합할 수도 있고, 때론 최적 적합이 적합한 방법일 수도 있습니다.

 

결국 어떤 알고리즘을 사용하더라도 외부 단편화의 문제는 발생할 수 있습니다.

 

외부 단편화 문제를 해결하는 가장 간단한 방법은 단순히 모든 프로세스를 한쪽 끝으로 이동시켜 모든 가용 공간이 반대 방향으로 모이도록 하는 방법(압축, Compaction)이지만 이 방법은 비용이 매우 많이 듭니다.

 

내부 단편화(Internal fragmentation)

단편화는 할당된 메모리 블록 내부에서도 발생할 수 있습니다. 예를 들어 메모리 할당 단위가 10MB이고 62MB 프로세스를 할당한다면, 실제로는 70MB(7개 블록)가 할당되어 8MB가 낭비됩니다. 이처럼 할당 단위의 배수로 메모리를 할당할 때 마지막 블록에서 사용되지 않는 공간이 생기는 것을 내부 단편화라고 합니다.

단편화 외에도 연속 메모리 할당 방식에는 더 치명적인 제약이 있습니다. 
   첫째, 프로세스의 크기가 현재 사용 가능한 최대 연속 공간의 크기를 초과할 수 없습니다.
   둘째, 프로세스가 물리 메모리 전체 크기보다 클 경우 아예 실행 자체가 불가능합니다. 예를 들어 3GB RAM을 가진 시스템에서 4GB가 필요한 프로그램은 실행할 방법이 없습니다. 이를 해결하기 위한 기법을 가상 메모리라고 합니다.

가상 메모리(Virtual Memory)

프로세스의 일부만 메모리에 적재하거나 보조 기억장치의 일부를 메모리 처럼 사용함으로써 실제 물리적인 메모리보다 큰 프로세스를 실행할 수 있게 하는 기법입니다. 이를 통해 메모리를 실제 크기보다 더 크게 보이게 만들 수 있으며, 대표적인 구현 방법으로 페이징(Paging)이 있습니다.

페이징(paging)

지금까지 이야기한 메모리 관리는 프로세스의 물리 주소 공간이 연속적이여야 했습니다. 페이징은 프로세스를 일정 단위로 나누어 비연속적으로 저장합니다. 물리 주소 공간이 연속으로 할당되지 않아도 된다는 이점을 가지기 때문에 연속 메모리 할당 방식의 가장 큰 문제인 외부 단편화와 압축의 필요성을 피할 수 있습니다. 페이징은 다음과 같이 구현 됩니다.

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

'Android' 카테고리의 다른 글

HiltViewModel 의존성 주입 원리  (0) 2025.11.06
아주 쉽게 알아보는 뷰가 그려지기까지의 여정  (0) 2025.10.29
안드로이드에서 네트워크 상태에 따라 API를 재호출해보자  (0) 2025.09.27
Retrofit Internals - Retrofit In Coroutine  (0) 2025.06.20
Retrofit Internals - Retrofit은 어떻게 인터페이스의 구현체를 만들까 ?  (1) 2025.06.16
'Android' 카테고리의 다른 글
  • HiltViewModel 의존성 주입 원리
  • 아주 쉽게 알아보는 뷰가 그려지기까지의 여정
  • 안드로이드에서 네트워크 상태에 따라 API를 재호출해보자
  • Retrofit Internals - Retrofit In Coroutine
빨주노초잠만보
빨주노초잠만보
  • 빨주노초잠만보
    과거의 나를 통해 미래의 나를 성장시키자
    빨주노초잠만보
  • 전체
    오늘
    어제
    • 분류 전체보기 (108)
      • 우아한테크코스 (6)
      • TEKHIT ANDROID SCHOOL (4)
      • Android Architecture (8)
      • Android (38)
      • PROJECT (11)
      • KOTLIN (10)
        • 코루틴의 정석 (3)
      • BACK END (12)
      • CS (4)
      • 컨퍼런스 (4)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    orbit
    안드로이드 디자인 시스템
    value class
    의존성 주입
    Two pass process
    DataSource
    android clean architecture
    DI
    android view lifecylce
    Repository Pattern
    process Context Switching
    Compose Typography
    MVI
    view 생명주기
    2025 우아콘 후기
    coroutine Context Switching
    Clean Architecture
    thread Context Switching
    flow
    컴포즈 디자인 시스템
    android Room
    ThrottleFirst
    sealed class
    Room
    STATEFLOW
    repository
    코틀린 코루틴의 정석
    callbackflow
    retrofit call
    Throttle
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
빨주노초잠만보
운영체제 메모리
상단으로

티스토리툴바