본문 바로가기

메모리 구조

@iamrain2025. 11. 17. 17:30

1. 메모리 구조

컴퓨터 메모리 구조는 프로그램과 데이터를 저장하기 위한 공간의 조직적인 설계와 계층을 의미합니다. 현대 컴퓨터 시스템은 단일한 메모리를 사용하는 대신, 메모리 계층 구조(Memory Hierarchy)라는 다계층 구조를 채택합니다.

이러한 계층 구조의 목적은 "성능", "용량", "비용" 이라는 세 가지 상충하는 요구사항 사이의 최적점을 찾는 것입니다. 일반적으로 메모리는 다음과 같은 특징을 가집니다.

  • 빠를수록(성능) -> 용량이 작고 -> 비트당 비용이 비싸다.
  • 느릴수록(성능) -> 용량이 크고 -> 비트당 비용이 저렴하다.

메모리 계층 구조는 CPU가 자주 접근하는 데이터는 빠르고 비싼 메모리에, 그렇지 않은 데이터는 느리고 저렴한 메모리에 저장함으로써, 평균적인 접근 속도를 높이고 대용량을 저렴하게 유지하는 전략입니다.

2. 컴퓨터 메모리 계층 구조 (Computer Memory Hierarchy)

메모리 계층은 CPU에 가까운 순서대로 레지스터, 캐시, 메인 메모리, 보조 기억장치로 구성됩니다.

가. 레지스터 (Registers)

  • 위치: CPU 내부에 존재합니다.
  • 속도: 가장 빠릅니다. CPU의 연산 속도와 거의 동일합니다.
  • 용량: 가장 작습니다. (수십 ~ 수백 Bytes)
  • 역할: CPU가 현재 처리 중인 명령어, 데이터, 주소 등을 임시로 저장합니다. 컴파일러는 최적화를 통해 변수나 연산 중간 결과를 레지스터에 할당하여 성능을 극대화합니다.
  • 주요 레지스터 종류:
    • PC (Program Counter): 다음에 실행할 명령어의 주소를 저장합니다.
    • IR (Instruction Register): 현재 실행 중인 명령어를 저장합니다.
    • MAR (Memory Address Register): 접근하려는 메모리의 주소를 저장합니다.
    • MDR (Memory Data Register): 메모리에서 읽거나 쓸 데이터를 임시 저장합니다.
    • 범용 레지스터 (General-Purpose Registers): 연산 데이터나 주소 등을 다목적으로 저장합니다.

나. 캐시 메모리 (Cache Memory)

  • 위치: CPU와 메인 메모리(RAM) 사이에 존재합니다.
  • 속도: 레지스터보다 느리지만, 메인 메모리보다 월등히 빠릅니다.
  • 용량: 레지스터보다 크지만, 메인 메모리보다 훨씬 작습니다. (수 KB ~ 수십 MB)
  • 역할: CPU와 메인 메모리 간의 속도 차이를 완화하는 버퍼 역할을 합니다. 지역성의 원리(Principle of Locality)를 기반으로 동작합니다.
    • 시간적 지역성 (Temporal Locality): 최근에 접근한 데이터는 가까운 미래에 다시 접근될 가능성이 높다. (예: 반복문 내의 변수)
    • 공간적 지역성 (Spatial Locality): 특정 데이터에 접근하면, 그 주변의 데이터에도 곧 접근할 가능성이 높다. (예: 배열 순회)
  • 구조 및 동작:
    • CPU가 데이터를 요청하면 먼저 캐시를 확인합니다. 데이터가 있으면 캐시 히트(Cache Hit)라 하며, 메인 메모리 접근 없이 바로 데이터를 사용합니다.
    • 데이터가 없으면 캐시 미스(Cache Miss)라 하며, 메인 메모리에서 해당 데이터를 찾아 캐시에 적재한 후 CPU로 전달합니다. 이때 공간적 지역성을 활용하기 위해 요청된 데이터뿐만 아니라 인접한 데이터를 포함하는 캐시 라인(Cache Line) 단위로 데이터를 가져옵니다.
    • L1, L2, L3 캐시: 현대 CPU는 여러 레벨의 캐시를 둡니다. L1은 CPU 코어에 가장 가깝고 가장 빠르며, L3는 가장 멀고 가장 느립니다.

다. 메인 메모리 (Main Memory / RAM)

  • 위치: 마더보드에 장착됩니다.
  • 속도: 캐시보다 느립니다.
  • 용량: 캐시보다 훨씬 큽니다. (수 GB ~ 수백 GB)
  • 역할: 현재 실행 중인 프로그램의 코드와 데이터를 저장하는 주 작업 공간입니다. 전원이 꺼지면 내용이 사라지는 휘발성(Volatile) 메모리입니다. (주로 DRAM 사용)
  • 프로세스의 메모리 구조: 운영체제는 메인 메모리를 여러 영역으로 나누어 각 프로세스에 할당합니다. (상세 내용은 3장에서 설명)

라. 보조 기억장치 (Secondary Storage)

  • 위치: 별도의 저장 장치 (HDD, SSD 등)
  • 속도: 가장 느립니다.
  • 용량: 가장 큽니다. (수백 GB ~ 수십 TB)
  • 역할: 전원이 꺼져도 데이터가 유지되는 비휘발성(Non-volatile) 메모리입니다. 파일 시스템을 통해 데이터를 영구적으로 저장하며, 가상 메모리 시스템에서 메인 메모리의 부족한 공간을 보충하는 스왑 공간(Swap Space)으로도 사용됩니다.

3. 프로세스의 메모리 구조 (Memory Layout of a Process)

운영체제는 프로세스를 실행할 때, 메인 메모리 내에 다음과 같은 논리적인 영역들을 할당합니다.

  • 코드 (Code) 영역: 실행 가능한 기계어 코드가 저장됩니다. CPU는 이 영역의 명령어들을 순차적으로 가져와 실행합니다. 데이터 변경을 막기 위해 보통 읽기 전용(Read-Only)으로 설정됩니다.
  • 데이터 (Data) 영역: 전역 변수(Global variables)와 정적 변수(Static variables)가 저장됩니다.
    • 초기화된 데이터 영역: int global_var = 10;과 같이 초기값이 있는 변수.
    • BSS (Block Started by Symbol) 영역: int global_var;와 같이 초기값이 없는 변수. 프로그램 시작 시 커널이 모두 0으로 초기화합니다.
  • 힙 (Heap) 영역: 프로그래머가 동적으로 메모리를 할당하는 공간입니다. malloc(), new 등으로 할당하고 free(), delete로 해제합니다. 낮은 주소에서 높은 주소 방향으로 자랍니다. 힙 영역의 메모리는 개발자가 명시적으로 해제하지 않으면 프로그램 종료 시까지 유지되므로, 메모리 누수의 주된 원인이 됩니다.
  • 스택 (Stack) 영역: 함수 호출 시 생성되는 지역 변수(Local variables), 매개변수(Parameters), 함수 반환 주소 등이 저장됩니다. LIFO(Last-In, First-Out) 구조를 가지며, 함수 호출 시 스택 프레임(Stack Frame)이 생성되고 함수 종료 시 사라집니다. 높은 주소에서 낮은 주소 방향으로 자랍니다.

4. 동작 계층 구조

  1. 사용자/프로그래머 레벨: C/C++ 코드에서 int a = b + c;와 같은 연산을 작성합니다.
  2. 컴파일러 레벨: 컴파일러는 이 코드를 기계어 코드로 변환합니다. 변수 bc를 레지스터로 가져오고, 덧셈 연산을 수행한 후, 결과를 다시 변수 a의 메모리 주소에 저장하는 명령어를 생성합니다. 이때 지역 변수는 스택, 전역 변수는 데이터 영역, 동적 할당은 힙 영역을 사용하도록 주소를 지정합니다.
  3. 운영체제 레벨: 프로그램이 실행되면, OS 로더(Loader)는 보조 기억장치에 있던 실행 파일을 메인 메모리에 적재하고, 위에서 설명한 코드/데이터/힙/스택 구조를 설정합니다.
  4. 하드웨어(CPU/MMU) 레벨:
    • CPU가 특정 메모리 주소(가상 주소)에 접근하는 명령을 실행합니다.
    • MMU(Memory Management Unit)가 이 주소를 받아서 먼저 L1 캐시에 데이터가 있는지 확인합니다. (Cache Hit -> 즉시 반환)
    • L1에 없으면 L2, L3 캐시를 순차적으로 확인합니다. (Cache Hit -> 반환)
    • 모든 캐시에 없으면(Cache Miss), MMU는 메인 메모리(RAM)에 접근하여 해당 주소의 데이터를 가져옵니다.
    • 가져온 데이터는 캐시 라인 단위로 캐시에 저장되고(미래의 접근을 위해), CPU 레지스터로 최종 전달되어 연산에 사용됩니다.

5. 요약

 컴퓨터의 메모리 구조는 CPU가 필요로 하는 데이터와 명령어를 효율적으로 저장하고 접근하기 위한 계층적 설계입니다. 가장 빠르지만 용량이 작은 CPU 내부의 '레지스터'부터 시작하여, CPU와 주 메모리 간의 속도 차이를 완충하는 '캐시 메모리', 실제 프로그램이 동작하는 '메인 메모리(RAM)', 그리고 대용량 데이터를 영구적으로 저장하는 '보조 기억장치' 순으로 계층을 이룹니다. 이러한 계층 구조는 '자주 사용하는 데이터는 더 빠른 메모리에 두자'는 지역성의 원리를 활용하여, 비용 대비 시스템 전체의 평균적인 메모리 접근 속도를 극대화하는 것을 목표로 합니다.

메모리 계층 구조가 필요한 이유는?

 메모리 계층 구조는 속도, 용량, 비용이 각기 다른 여러 종류의 저장장치를 계층적으로 구성한 것입니다. CPU는 매우 빠르지만, 대용량 메모리를 CPU 속도에 맞추는 것은 비용 문제로 불가능합니다. 따라서 CPU에 가까울수록 빠르고 비싸고 용량이 작은 메모리(레지스터, 캐시)를, 멀어질수록 느리고 저렴하며 용량이 큰 메모리(RAM, SSD/HDD)를 배치합니다. 이를 통해 비용 효율적인 시스템 설계와 함께 평균 접근 시간을 단축하여 전체 시스템 성능을 향상시킬 수 있습니다.

캐시 메모리의 지역성 원리

 지역성의 원리는 프로그램이 메모리에 접근하는 패턴이 예측 가능하다는 성질을 말하며, 시간적 지역성과 공간적 지역성으로 나뉩니다. 시간적 지역성은 한번 접근한 데이터는 가까운 미래에 다시 접근될 확률이 높다는 원리입니다. 예를 들어, 반복문에서 사용되는 변수가 있습니다. 공간적 지역성은 특정 데이터에 접근했을 때, 그 주변의 데이터에도 곧 접근할 확률이 높다는 원리입니다. 예를 들어, 배열의 원소를 순차적으로 접근하는 경우가 해당됩니다. 캐시 메모리는 이 두 가지 지역성 원리를 활용하여, 메인 메모리에서 데이터를 가져올 때 특정 블록(캐시 라인) 단위로 가져와 CPU의 다음 요청이 캐시 내에서 처리될 확률(캐시 히트율)을 높입니다.

프로세스의 메모리 구조에서 스택과 힙의 차이점은?

 스택과 힙은 모두 프로그램 실행 중에 사용되는 메모리 공간이지만, 관리 방식과 용도에서 큰 차이가 있습니다. 스택은 함수의 호출과 함께 할당되며 지역 변수, 매개변수 등이 저장됩니다. 컴파일러에 의해 크기가 계산되고 운영체제가 자동으로 관리하며, LIFO(후입선출) 방식으로 동작하여 속도가 매우 빠릅니다. 반면, 은 프로그래머가 필요에 따라 동적으로 메모리를 할당하고 해제하는 공간입니다. malloc이나 new 연산자를 통해 할당되며, 스택보다 속도가 느리고 관리가 복잡하여 메모리 누수나 단편화 같은 문제가 발생할 수 있습니다. 또한, 스택은 높은 주소에서 낮은 주소로, 힙은 낮은 주소에서 높은 주소로 자라나는 차이점도 있습니다.

'Computer Science' 카테고리의 다른 글

CPU  (0) 2025.11.19
가상 메모리 Virtual Memory  (0) 2025.11.17
깊은 복사와 얕은 복사  (0) 2025.11.14
Red-Black 트리  (0) 2025.11.13
교착 상태 (Deadlock)  (0) 2025.11.12
iamrain
@iamrain :: Annals of Unreal

iamrain 님의 블로그 입니다.

공감하셨다면 ❤️ 구독도 환영합니다! 🤗

목차