코딩의 신 80

김동관·2026년 1월 28일

C#의 심화

메모리 & 런타임

Stack vs Heap

int a = 10;
Player player = new Player();

a → Stack

player → Heap

player 변수 자체는 Stack에 있고
실제 객체는 Heap에 있음

Heap 객체가 많아지면 → GC 발생

GC 발생 → 프레임 드랍

GC (Garbage Collection)

GC란?

참조가 끊긴 Heap 객체를 정리 Unity에서는 프레임 중단(stall) 발생

new Class()
new List<int>()
string += "text"
LINQ
Instantiate / Destroy
// GC를 유발하는 대표적인 것들

<<해결방법>>
Object Pooling, List 재사용, string concat 최소화

값 타입 vs 참조 타입 (struct vs class)

class ?

Heap 할당, 참조 전달, GC 대상

사용 상황: 작은 데이터, 불변 성격, 자주 생성/파괴됨

struct?

Stack 할당 (또는 inline), 값 복사, GC 없음

사용 상황 : 상태 변경 많음, 공유 필요, 크기 큼
struct DamageInfo {
    public int damage;
}

delegate / event (Update를 없애는 핵심)

Update 문제

void Update() {
    CheckHp();
}
// 매 프레임 실행, 대부분 의미 없는 검사

event 방식

public event Action<int> OnHpChanged;

public void TakeDamage(int dmg) {
    hp -= dmg;
    OnHpChanged?.Invoke(hp);
}
//  필요할 때만 실행, 성능 + 구조 둘 다 개선

<< 상태 변화는 polling이 아니라 event로 처리 >>

interface vs abstract class

interface?

구현 강제, 다중 구현 가능, 기능 계약서

interface IDamageable {
    void TakeDamage(int dmg);
}
// 플레이어, 몬스터, 구조물 전부 가능

abstract class

공통 로직 + 일부 강제

abstract class Character {
    public abstract void Die();
}
선택 기준 : “기능만 필요” → interface , “공통 상태/로직” → abstract

Generic (T) = 재사용 + 타입 안정성

class ObjectPool<T> where T : MonoBehaviour

//캐스팅 제거, 코드 재사용, 컴파일 타임 안정성

async / await & Thread

Unity API는 메인 스레드 전용
await Task.Run(() => LoadData());
//데이터 로딩 , GameObject 접근 -> 계산 / 로딩만 비동기, 결과 적용은 메인 스레드

Unity 최적화 핵심 개념들

Draw Call

같은 머티리얼 → Batch

다른 머티리얼 → DrawCall 증가

UI Canvas 분리 이유

전체 Canvas 리빌드를 막기 위해

Object Pooling

obj.SetActive(false);
// Destroy x, 재사용 

아키텍처 사고 방식

역할 분리
QuestManager → 퀘스트 상태
UI → 표시만
DataManager → 데이터

// 좋은 구조란? 수정 시 영향 범위가 좁다,테스트가 쉽다.

이상 유니티와 C#의 심화 개념이었습니다.

profile
아이디어 뱅크

0개의 댓글