본문 바로가기

C#/기본 문법

C# 메모리 영역

1) 메모리 구조

┌──────────────────────────────┐
│        코드(Code) 영역        │ ← 실행할 명령어 저장
├──────────────────────────────┤
│      정적/데이터(Static) 영역 │ ← static 변수, 상수
├──────────────────────────────┤
│            힙(Heap)           │ ← 참조 타입 (클래스, 배열, 문자열)
│            ↑ ↓ (GC 관리)     │
├──────────────────────────────┤
│            스택(Stack)        │ ← 지역 변수, 매개변수, 값 타입
│       (함수 호출 시 생성/해제)│
└──────────────────────────────┘

 

1️⃣ 스택(Stack)

  • 함수가 호출될 때 스택 프레임(Stack Frame) 이 생성됩니다.
  • 지역 변수, 매개변수, 값 타입(struct, int, bool, float 등) 이 여기에 저장됩니다.
  • 함수가 끝나면 해당 스택 프레임이 제거되면서 자동으로 해제됩니다.

💡 특징

  • 빠름 (LIFO 구조)
  • 자동 해제
  • 값 타입은 복사로 전달됨 (단, ref 사용 시 참조 전달 가능)
  • ex) C# 구조체로 ref 키워드를 사용해서 함수에 넘길때 stack 안에 있는 주소를 가리킴

ref 사용 예시

using System;
using System.Numerics;

namespace Rookiss_CSharp
{
    class Program
    {
        struct Mage
        {
            public int hp;
            public int attack;
        }
        
        static void HealMage(ref Mage mage) // stack 안에 있는 Main(string[] args) -> mage 변수의 주소 가리킴
        {
            mage.hp += 30;
        }

        static void Main(string[] args)
        {
            Mage mage;
            // Mage mage = new Mage();
            mage.hp = 100;
            mage.attack = 50;
            HealMage(ref mage);
        }
    }
}

 

 

stack 예시

void Foo()
{
    int x = 10;       // Stack에 x=10 저장
    int y = 20;       // Stack에 y=20 저장
    int sum = x + y;  // Stack에 sum=30 저장
} // Foo 종료 시 x, y, sum 사라짐

 

2️⃣ 힙(Heap)

  • 클래스 객체, 배열, 문자열참조 타입(reference type) 은 힙에 저장됩니다.
  • 변수에는 실제 데이터가 아니라 힙 메모리 주소(참조값) 가 저장됩니다.
  • 가비지 컬렉터(GC)가 더 이상 참조되지 않는 객체를 자동으로 해제합니다.

💡 특징

  • 상대적으로 느림 (동적 할당)
  • 참조 타입이 저장됨
  • 수동 해제 불필요 (GC가 관리)

참고

  • 동적할당하고 해제하지 않으면 Heap에 계속 남아있음
    • (C++은 직접해줘야하고, C#은 더이상 가리키는 변수가 없으면 가비지 컬렉터에 의해 자동 해제됨)

 

🧠 예시

class Player
{
    public int hp;
}

void Main()
{
    Player p1 = new Player();  // p1은 스택에, new Player()는 힙에 생성
    p1.hp = 100;
}

 

메모리 구조:

[Stack]
p1 ─────────┐
             ▼
[Heap]
Player object
  hp = 100

 

3️⃣ 정적 영역 (Static / Data Area)

  • static 키워드가 붙은 변수나 상수, 전역 변수 등이 여기에 저장됩니다.
  • 프로그램이 시작될 때 할당되고, 종료될 때까지 유지됩니다.

💡 특징

  • 전역적으로 접근 가능
  • 프로그램이 끝날 때까지 해제되지 않음

🧠 예시

class Game
{
    public static int playerCount = 0;
}
  • Game.playerCount는 정적 메모리 영역에 존재.
  • 프로그램 종료 전까지 계속 남아 있음.

 

4️⃣ (참고) 상수(Constant) 영역 / 문자열 풀(String Intern Pool)

  • 리터럴 상수(const, 문자열 리터럴 등)는 특별한 메모리 영역(읽기 전용 데이터 영역)에 저장됩니다.
  • 문자열은 String Intern Pool에 저장되어 중복 생성 방지됩니다.

🧠 예시:

string s1 = "Hello";
string s2 = "Hello";
Console.WriteLine(object.ReferenceEquals(s1, s2)); // True

→ "Hello"는 문자열 풀에 한 번만 저장되어, 두 변수 모두 같은 주소를 참조합니다.

 

 

📌 핵심 요약

구분 저장 대상 생명주기 관리 방식
Stack 값 타입, 지역 변수 함수 실행 중 자동
Heap 참조 타입 (클래스, 배열) 참조가 끊길 때 GC가 해제
Static 영역 static 변수, 상수 프로그램 전체 자동
String Pool 문자열 리터럴 전역적 CLR 관리

 

출처

https://www.inflearn.com/courses/lecture?courseId=324718&roadmapId=355&tab=curriculum&type=LECTURE&unitId=32807&subtitleLanguage=ko

 

스택과 힙 | [C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part1: C# 기초 프로그래밍 입문

스택과 힙

www.inflearn.com

37ㄱ 스택과 힙

'C# > 기본 문법' 카테고리의 다른 글

C# static  (0) 2025.11.01
C# 생성자  (0) 2025.11.01
C# 객체 지향 시작 및 복사와 값 참조  (0) 2025.11.01
C# TextRPG  (0) 2025.11.01
C# 간단한 연습문제  (0) 2025.10.27