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 |