메모리 구조 (스택, 힙, 데이터 영역)

코딩C언어JavaPython
읽는데 17분 소요
처음 쓰여진 날: 2026-02-03
마지막 수정일: 2026-02-19
조회수: 36

요약

프로그램의 메모리 구조를 알아봅니다. 스택(Stack)과 힙(Heap)의 차이, 컴파일 시점과 런타임의 메모리 할당 차이를 이해하면 동적 메모리 할당과 Garbage Collection을 쉽게 이해할 수 있습니다.

메모리 구조 핵심 정리

영역저장 내용크기 결정해제 방식
코드(Code)프로그램 코드컴파일 시-
데이터(Data)전역 변수, 정적 변수컴파일 시프로그램 종료 시
스택(Stack)지역 변수, 함수 호출 정보1컴파일 시자동 (함수 종료 시)
힙(Heap)동적 할당 메모리런타임 시수동 (free 호출)

메모리 구조 핵심 정리

영역저장 내용크기 결정해제 방식
코드(Code)바이트코드 (메서드 영역)클래스 로딩 시-
데이터(Data)static 필드, 클래스 메타데이터클래스 로딩 시프로그램 종료 시
스택(Stack)지역 변수, 메서드 호출 정보1컴파일 시자동 (메서드 종료 시)
힙(Heap)객체, 배열 (new로 생성)런타임 시자동 (GC가 회수)

메모리 구조 핵심 정리

영역저장 내용크기 결정해제 방식
코드(Code)바이트코드 (.pyc)임포트 시-
데이터(Data)전역 변수, 모듈 레벨 객체런타임 시프로그램 종료 시
스택(Stack)함수 호출 프레임1 (지역 변수의 참조)런타임 시자동 (함수 종료 시)
힙(Heap)모든 객체 (정수, 문자열, 리스트 등)런타임 시자동 (GC가 회수)

프로그램 메모리 구조

C 프로그램이 실행되면 운영체제가 메모리를 4개 영역으로 나누어 할당합니다.

Java 프로그램이 실행되면 JVM2이 메모리를 여러 영역으로 나누어 관리합니다. 기본 구조는 C와 동일하게 코드, 데이터, 힙, 스택 영역으로 나뉩니다.

Python 프로그램이 실행되면 CPython3 인터프리터가 메모리를 관리합니다. Python에서는 모든 값이 객체이므로, 정수나 문자열까지 포함해 대부분의 데이터가 힙에 저장됩니다.

프로그램 메모리 구조
메모리는 코드, 데이터, 힙, 스택 영역으로 나뉩니다. 힙은 위에서 아래로, 스택은 아래에서 위로 자랍니다.

힙과 스택은 메모리의 빈 공간에서 서로 마주보며 자랍니다. 힙은 아래로, 스택은 위로 확장되다가 만나면 메모리 부족(Out of Memory) 이 발생합니다.

영역설명
코드 영역실행할 프로그램 코드가 저장됩니다
데이터 영역전역 변수와 static 변수가 저장됩니다
힙 영역malloc()으로 할당한 메모리가 저장됩니다
스택 영역지역 변수와 함수 호출 정보1가 저장됩니다
영역설명
코드 영역컴파일된 바이트코드(메서드 영역)가 저장됩니다
데이터 영역static 필드와 클래스 메타데이터가 저장됩니다
힙 영역new로 생성한 객체와 배열이 저장됩니다
스택 영역지역 변수와 메서드 호출 정보1가 저장됩니다
영역설명
코드 영역컴파일된 바이트코드(.pyc)가 저장됩니다
데이터 영역전역 변수와 모듈 레벨 객체가 저장됩니다
힙 영역모든 객체(정수, 문자열, 리스트 등)가 저장됩니다
스택 영역함수 호출 프레임1과 지역 변수의 참조가 저장됩니다

왜 이런 순서일까?

  • 코드/데이터 영역이 낮은 주소에 있는 이유: 프로그램 시작 시 가장 먼저 로드되고, 크기가 고정되어 있어서 미리 자리를 잡아둡니다.
  • 힙과 스택이 양 끝에서 자라는 이유: 둘 다 크기가 가변적이므로, 빈 공간을 최대한 활용하기 위해 반대 방향으로 자랍니다.

스택(Stack) 영역

스택 은 함수 호출 정보1와 지역 변수4를 관리하는 영역입니다.

스택 은 메서드 호출 정보1, 지역 변수4, 그리고 객체의 참조(주소) 를 관리하는 영역입니다.

스택 은 함수 호출 정보1와 지역 변수4참조(이름) 를 관리하는 영역입니다.

스택의 특징

  • LIFO(Last In First Out): 나중에 들어온 데이터가 먼저 나갑니다
  • 자동 할당/해제: 함수가 호출되면 할당, 종료되면 자동 해제
  • 크기 고정: 컴파일 시점에 크기가 결정됩니다
c
코드 하이라이팅 중...
java
코드 하이라이팅 중...

Java에서 기본형5(int, double 등)은 스택에 직접 저장되지만, 객체와 배열은 에 생성되고 스택에는 참조(주소) 만 저장됩니다.

python
코드 하이라이팅 중...

Python에서는 모든 값이 객체입니다. a = 10이라고 써도 정수 10은 힙에 생성된 객체이고, 스택에는 그 객체를 가리키는 참조(이름) 만 저장됩니다.

스택 오버플로우

스택 크기는 제한되어 있어서, 너무 큰 배열을 선언하거나 재귀 호출이 너무 깊으면 스택 오버플로우(Stack Overflow) 가 발생합니다. 스택 메모리가 한계를 넘으면 운영체제가 프로그램을 강제 종료시킵니다.

c
코드 하이라이팅 중...

스택 크기는 제한되어 있어서, 재귀 호출이 너무 깊으면 StackOverflowError가 발생합니다.

java
코드 하이라이팅 중...

Java에서는 C와 달리 큰 배열을 선언해도 스택 오버플로우가 발생하지 않습니다. 배열은 항상 에 생성되기 때문입니다.

스택 크기는 제한되어 있어서, 재귀 호출이 너무 깊으면 RecursionError가 발생합니다. Python은 기본적으로 재귀 깊이를 1,000회로 제한합니다.

python
코드 하이라이팅 중...

데이터(Data) 영역

데이터 영역은 프로그램이 시작할 때 할당되고, 종료될 때 해제되는 영역입니다. 전역 변수static 변수가 이 영역에 저장됩니다.

c
코드 하이라이팅 중...

static 변수는 함수 안에 선언되어 있지만, 데이터 영역에 저장되어 함수가 종료되어도 값이 유지됩니다.

데이터 영역(메서드 영역)은 JVM이 클래스를 로딩할 때 할당됩니다. static 필드와 클래스 메타데이터가 이 영역에 저장됩니다.

java
코드 하이라이팅 중...

static 필드는 객체가 아니라 클래스에 속하는 변수입니다. 모든 인스턴스가 같은 값을 공유합니다.

데이터 영역에는 모듈 레벨(파일 최상위)에서 정의된 전역 변수와 클래스 객체가 저장됩니다.

python
코드 하이라이팅 중...

Python의 클래스 속성은 Java의 static 필드와 비슷하게, 모든 인스턴스가 같은 값을 공유합니다.



힙(Heap) 영역

은 프로그래머가 직접 관리하는 동적 메모리 영역입니다.

힙의 특징

  • 런타임 할당: 프로그램 실행 중에 크기 결정 가능
  • 수동 관리: malloc()으로 할당, free()로 해제 (#include <stdlib.h> 필요)
  • 유연한 크기: 큰 데이터도 저장 가능
c
코드 하이라이팅 중...

메모리 누수

free()를 호출하지 않으면 메모리 누수(Memory Leak) 가 발생합니다.

메모리 누수란? malloc()으로 할당받은 메모리를 free()로 반환하지 않아서, 더 이상 사용하지 않는 메모리가 힙에 계속 쌓이는 현상입니다.

c
코드 하이라이팅 중...

왜 문제가 되나요?

상황결과
단발성 프로그램종료 시 OS가 모든 메모리 회수 → 큰 문제 없음
장시간 실행 (서버, 게임 등)메모리가 계속 쌓여서 시스템이 느려지거나 다운

메모리 누수 방지: malloc() 호출 횟수와 free() 호출 횟수가 항상 일치해야 합니다.

c
코드 하이라이팅 중...

new 키워드로 생성한 모든 객체와 배열이 저장되는 영역입니다.

힙의 특징

  • 런타임 할당: 프로그램 실행 중에 객체 생성
  • 자동 관리: Garbage Collector(GC)가 미사용 객체를 자동 회수
  • 모든 객체가 힙에 저장: new로 생성한 것은 모두 힙에 위치
java
코드 하이라이팅 중...

Java에서는 C와 달리 free()를 호출할 필요가 없습니다. Garbage Collector가 더 이상 참조되지 않는 객체를 자동으로 회수합니다.

String 리터럴은 힙 내부의 String Pool 이라는 특별한 공간에 저장됩니다. 자세한 내용은 문자열의 기초를 참고하세요.

은 Python의 모든 객체가 저장되는 영역입니다. 정수, 문자열, 리스트, 딕셔너리까지 전부 힙에 생성됩니다.

힙의 특징

  • 런타임 할당: 프로그램 실행 중에 객체 생성
  • 자동 관리: Reference Counting + GC가 미사용 객체를 자동 회수
  • 모든 것이 객체: 숫자, 문자열, 함수까지 전부 힙에 저장
python
코드 하이라이팅 중...

Python에서는 C/Java와 달리 기본형(primitive type)이 없습니다. 42조차 int 객체이며 힙에 저장됩니다. 다만 자주 사용하는 작은 정수(-5 ~ 256)는 미리 캐싱해두어 재사용합니다.


스택 vs 힙 비교

스택과 힙 비교
스택은 자동으로 관리되고, 힙은 malloc/free로 수동 관리합니다.
구분스택
할당 방식자동malloc()
해제 방식자동 (함수 종료)free() 호출
크기 결정컴파일 시런타임 시
속도빠름느림
크기 제한작음 (보통 1 ~ 8MB)큼 (시스템 메모리)
사용 예지역 변수, 배열동적 배열, 연결 리스트
구분스택
저장 대상기본형 변수, 참조 변수객체, 배열
할당 방식자동new 키워드
해제 방식자동 (메서드 종료)GC가 자동 회수
크기 결정컴파일 시런타임 시
속도빠름느림
스레드 공유스레드마다 별도모든 스레드가 공유
구분스택
저장 대상함수 호출 프레임, 참조(이름)모든 객체 (정수, 문자열, 리스트 등)
할당 방식자동 (함수 호출 시)자동 (객체 생성 시)
해제 방식자동 (함수 종료)GC가 자동 회수
크기 제한재귀 깊이 1,000회 (기본값)시스템 메모리

컴파일 시점 vs 런타임

일반 변수와 배열은 컴파일할 때 크기가 결정되고, 동적 메모리는 런타임(실행 중) 에 결정됩니다. 자세한 내용은 컴파일과 런타임의 차이를 참고하세요.

c
코드 하이라이팅 중...

동적 메모리 할당을 사용하면 사용자 입력이나 조건에 따라 실행 중에 크기를 결정할 수 있습니다.


왜 동적 메모리 할당이 필요한가?

1. 크기를 미리 알 수 없는 경우

c
코드 하이라이팅 중...

2. 큰 데이터를 저장해야 하는 경우

c
코드 하이라이팅 중...

3. 유연한 자료구조 구현

연결 리스트처럼 크기가 변하는 자료구조는 동적 메모리 할당이 필수입니다.

c
코드 하이라이팅 중...

다음 단계

메모리 구조를 이해했다면, 동적 메모리 할당에서 malloc()free() 함수의 구체적인 사용법을 학습하세요.


Garbage Collection (가비지 컬렉션)

Java는 C와 달리 프로그래머가 메모리를 직접 해제하지 않습니다. Garbage Collector(GC) 가 힙 영역에서 더 이상 참조되지 않는 객체를 자동으로 찾아서 회수합니다.

java
코드 하이라이팅 중...

C와의 차이점

구분CJava
메모리 해제free() 수동 호출GC가 자동 회수
메모리 누수free() 누락 시 발생GC 덕분에 거의 발생하지 않음
개발 편의성메모리 관리에 신경 써야 함메모리 관리를 JVM에 위임

다음 단계

Java의 메모리 구조를 이해했다면, 문자열의 기초에서 String Pool과 == vs equals() 비교를 학습하세요.


Garbage Collection (가비지 컬렉션)

Python은 Reference Counting(참조 카운팅) 을 기본 메모리 관리 방식으로 사용합니다. 객체를 참조하는 변수가 0개가 되면 즉시 메모리를 해제합니다.

python
코드 하이라이팅 중...

id() 함수로 객체 확인하기

id() 함수는 객체의 메모리 주소(고유 식별자) 를 반환합니다. 두 변수가 같은 객체를 가리키는지 확인할 수 있습니다.

python
코드 하이라이팅 중...

C, Java와의 차이점

구분CJavaPython
메모리 해제free() 수동 호출GC가 자동 회수Reference Counting + GC
메모리 누수free() 누락 시 발생거의 발생하지 않음거의 발생하지 않음
기본형 저장 위치스택스택힙 (모든 것이 객체)

다음 단계

Python의 메모리 구조를 이해했다면, 문자열의 기초에서 인덱싱, 슬라이싱 등 Python 문자열 핵심 개념을 학습하세요.


Footnotes

  1. 함수(메서드) 호출 정보란 함수가 호출될 때 스택에 쌓이는 데이터를 말합니다. 매개변수, 지역 변수, 그리고 함수 실행이 끝난 뒤 돌아갈 위치(리턴 주소)가 하나의 스택 프레임(Stack Frame) 으로 묶여 저장됩니다. 함수가 종료되면 해당 프레임이 스택에서 제거됩니다. 2 3 4 5 6 7 8 9

  2. JVM(Java Virtual Machine)은 Java 프로그램을 실행하는 가상 머신입니다. Java 소스 코드는 컴파일러가 바이트코드(.class)로 변환하고, JVM이 이 바이트코드를 해석하여 운영체제 위에서 실행합니다. 덕분에 같은 Java 코드가 Windows, Mac, Linux 어디서든 동작합니다.

  3. CPython은 Python의 공식 표준 구현체로, C 언어로 작성된 인터프리터입니다. python 명령어로 실행하면 기본적으로 CPython이 동작합니다. Python 코드를 바이트코드(.pyc)로 변환한 뒤 이를 해석하여 실행하며, 메모리 관리에 참조 카운팅(Reference Counting) 방식을 사용합니다.

  4. 지역 변수란 함수(메서드) 안에서 선언된 변수입니다. 함수가 호출될 때 생성되고, 함수가 종료되면 자동으로 사라집니다. 함수 바깥에서는 접근할 수 없습니다. 2 3

  5. 기본형(Primitive Type)은 int, double, char, boolean 등 값 자체를 직접 저장하는 자료형입니다. 반대로 String, int[], 클래스 객체 등은 참조형(Reference Type)으로, 스택에는 주소만 저장되고 실제 데이터는 힙에 저장됩니다.