C#의 심화
메모리 & 런타임
int a = 10;
Player player = new Player();
a → Stack
player → Heap
player 변수 자체는 Stack에 있고
실제 객체는 Heap에 있음
Heap 객체가 많아지면 → GC 발생
GC 발생 → 프레임 드랍
GC (Garbage Collection)
참조가 끊긴 Heap 객체를 정리 Unity에서는 프레임 중단(stall) 발생
new Class()
new List<int>()
string += "text"
LINQ
Instantiate / Destroy
// GC를 유발하는 대표적인 것들
<<해결방법>>
Object Pooling, List 재사용, string concat 최소화
값 타입 vs 참조 타입 (struct vs class)
Heap 할당, 참조 전달, GC 대상
Stack 할당 (또는 inline), 값 복사, GC 없음
struct DamageInfo {
public int damage;
}
delegate / event (Update를 없애는 핵심)
void Update() {
CheckHp();
}
// 매 프레임 실행, 대부분 의미 없는 검사
public event Action<int> OnHpChanged;
public void TakeDamage(int dmg) {
hp -= dmg;
OnHpChanged?.Invoke(hp);
}
// 필요할 때만 실행, 성능 + 구조 둘 다 개선
<< 상태 변화는 polling이 아니라 event로 처리 >>
interface vs abstract class
구현 강제, 다중 구현 가능, 기능 계약서
interface IDamageable {
void TakeDamage(int dmg);
}
// 플레이어, 몬스터, 구조물 전부 가능
공통 로직 + 일부 강제
abstract class Character {
public abstract void Die();
}
Generic (T) = 재사용 + 타입 안정성
class ObjectPool<T> where T : MonoBehaviour
//캐스팅 제거, 코드 재사용, 컴파일 타임 안정성
await Task.Run(() => LoadData());
//데이터 로딩 , GameObject 접근 -> 계산 / 로딩만 비동기, 결과 적용은 메인 스레드
Unity 최적화 핵심 개념들
같은 머티리얼 → Batch
다른 머티리얼 → DrawCall 증가
전체 Canvas 리빌드를 막기 위해
obj.SetActive(false);
// Destroy x, 재사용
QuestManager → 퀘스트 상태
UI → 표시만
DataManager → 데이터
// 좋은 구조란? 수정 시 영향 범위가 좁다,테스트가 쉽다.
이상 유니티와 C#의 심화 개념이었습니다.