728x90
📘 Chapter 3.6: .NET 메모리 관리 이해 – GC 동작 원리
✅ 이 챕터에서 배울 것
- .NET의 메모리 구조 (스택 vs 힙)
- GC가 왜 필요한가?
- GC의 세대별 구조 (Gen 0, 1, 2)
- 객체 수명과 Promotion
- Large Object Heap(LOH) 개념
- Finalizer, IDisposable 차이
- 성능 최적화 팁
1️⃣ .NET의 메모리 구조
영역 | 역할 |
---|---|
스택(Stack) | 지역 변수, 메서드 호출, 빠름 |
힙(Heap) | new로 만든 객체, GC가 관리 |
int x = 10; // 스택에 저장
var list = new List<int>(); // 힙에 저장
2️⃣ GC란?
“사용 안 하는 객체는 내가 알아서 치워줄게”
GC는 메모리 누수 방지 + 자동 관리를 해주는 .NET의 똑똑한 청소부다
💡 근데 왜 필요하노?
- C++은 delete 직접 해줘야 함
- 누수 터지면 디버깅 지옥
- .NET은 GC가 주기적으로 스캔하면서 사용 안 하는 객체를 수거해간다
3️⃣ GC의 세대(Generation)
🔁 GC는 모든 객체를 매번 검사하지 않는다!
.NET은 힙을 3개의 세대로 나눠서 가성비 좋게 청소한다
세대 | 설명 |
---|---|
Gen 0 | 새로 생성된 객체 (빠르게 검사) |
Gen 1 | Gen 0에서 살아남은 중간 객체 |
Gen 2 | 장기 생존 객체 (가끔만 검사) |
📌 대부분 객체는 Gen 0에서 생성 → 바로 GC됨
→ 살아남는 애들만 점점 윗세대로 승격(Promotion)됨
✅ Promotion 흐름
new 객체 → Gen 0
GC에서 안 치워짐 → Gen 1
또 안 치워짐 → Gen 2
➡️ Gen 2는 무겁기 때문에 최대한 안 건드리는 게 성능에 좋다
4️⃣ Large Object Heap (LOH)
💥 “10만 바이트 이상”이면 LOH에 들어간다!
var bigArray = new byte[1024 * 100]; // 100KB 이상 → LOH
특징 | 설명 |
---|---|
GC 대상은 맞지만 | Gen 2에서만 청소됨 |
단점 | 파편화(Fragmentation) 발생 가능성 |
주의 | 잦은 LOH 할당 → 성능 병목 발생 |
5️⃣ Finalizer vs IDisposable
✅ Finalizer (~소멸자)
~MyClass()
{
Console.WriteLine("GC가 치우기 전에 호출됨");
}
- GC가 수거하기 전에 호출됨
- 정확한 시점 보장 안 됨
- 성능 좋지 않음
✅ IDisposable
public class MyClass : IDisposable
{
public void Dispose()
{
// 리소스 해제
}
}
✅ using문과 함께 사용
using var conn = new SqlConnection(...);
- 명시적 해제 가능
- 실무에선 거의 IDisposable 우선 사용
6️⃣ 실무 성능 팁
팁 | 설명 |
---|---|
객체 재사용 | 매번 new 하지 말고 풀링 고려 |
Dispose 잘하기 | IDisposable 있는 건 꼭 using 써라 |
Finalizer 남용 금지 | GC 부담 가중됨 |
LOH 피하기 | 큰 배열은 pooling하거나 나눠 써라 |
GC.Collect() 금지 | 절대 직접 부르면 안 된다! 성능 최악! |
✅ GC 상태 확인법 (디버깅용)
Console.WriteLine(GC.GetGeneration(myObj)); // 0, 1, 2 중 출력
Console.WriteLine(GC.MaxGeneration); // 2
✅ 정리 요약
항목 | 설명 |
---|---|
스택 vs 힙 | 힙은 GC가 관리하는 영역 |
GC 역할 | 객체를 자동으로 수거 |
Gen 0/1/2 | 세대별로 청소 전략 다름 |
LOH | 85KB 이상 객체, 성능 병목 주의 |
IDisposable | 명시적 자원 해제에 필수 |
실무 팁 | GC에 친화적인 코드 쓰기 |
📢 다음 챕터 예고 🎓
다음 챕터 | 주제 |
---|---|
Chapter 3.7 | 커스텀 Attributes, AOP 기법 적용 |
728x90
'C#' 카테고리의 다른 글
C# 기초부터 고급까지 Chapter 3.8. Domain-Driven Design(DDD) 도입과 구조 설계 (1) | 2025.05.12 |
---|---|
C# 기초부터 고급까지 Chapter 3.7. 커스텀 Attributes, AOP 기법 적용 (1) | 2025.05.11 |
C# 기초부터 고급까지 Chapter 3.5. 코드 분석 및 성능 측정 도구 사용 (BenchmarkDotNet 등) (2) | 2025.05.07 |
C# 기초부터 고급까지 Chapter 3.4. 고급 LINQ 커스터마이징 & 쿼리 최적화 (2) | 2025.05.06 |
C# 기초부터 고급까지 Chapter 3.3. Expression Tree로 컴파일 타임 코드 생성 (17) | 2025.05.05 |