API를 사용한 GC 모니터링

.NET 애플리케이션에서 GCGarbage Collector의 상태를 실시간으로 모니터링하려면 GC 클래스와 .NET에서 제공하는 다양한 API를 활용할 수 있습니다. 이를 통해 앱 내부에서 메모리 사용량, 세대별 GC 수행 횟수, 힙 상태 등을 간단히 추적하고 관리할 수 있습니다.

GC 모니터링을 위한 주요 API

GetTotalMemory

현재 메모리 사용량 확인
앱에서 사용 중인 총 메모리 크기를 반환합니다.

long memoryUsed = GC.GetTotalMemory(false); // false: 강제 GC 없이 메모리 사용량 반환
Console.WriteLine($"Total Memory: {memoryUsed} bytes");
  • 애플리케이션 실행 중 메모리 사용량 변화를 실시간으로 확인.
  • 특정 작업(예: 대규모 객체 생성) 이후 메모리 사용량 비교.

CollectionCount

세대별 GC 수행 횟수 확인
지정된 세대에서 발생한 GC 수행 횟수를 반환합니다.

int gen0Collections = GC.CollectionCount(0); // 0세대
int gen1Collections = GC.CollectionCount(1); // 1세대
int gen2Collections = GC.CollectionCount(2); // 2세대

Console.WriteLine($"Gen 0 Collections: {gen0Collections}");
Console.WriteLine($"Gen 1 Collections: {gen1Collections}");
Console.WriteLine($"Gen 2 Collections: {gen2Collections}");
  • 특정 작업에서 GC가 빈번히 호출되는지 확인.
  • 비효율적인 메모리 할당이나 수집 빈도 분석.

GetGeneration

특정 객체가 속한 GC 세대를 반환합니다.

object obj = new object();
Console.WriteLine($"Object Generation: {GC.GetGeneration(obj)}");
  • 긴 수명 객체가 2세대로 승격되었는지 확인.
  • 특정 객체의 생애주기를 분석하여 메모리 관리 최적화.

MaxGeneration

GC에서 관리하는 세대의 최대 값을 반환합니다.

Console.WriteLine($"Max Generation: {GC.MaxGeneration}");
  • 현재 시스템에서 GC 세대 구조 이해.
  • 일반적으로 2 리턴

GetGCMemoryInfo

GC 힙과 관련된 다양한 정보를 포함하는 GCMemoryInfo 객체를 반환합니다.

var memoryInfo = GC.GetGCMemoryInfo();
Console.WriteLine($"Heap Size: {memoryInfo.HeapSizeBytes} bytes");
Console.WriteLine($"Total Available Memory: {memoryInfo.TotalAvailableMemoryBytes} bytes");
Console.WriteLine($"Memory Load: {memoryInfo.MemoryLoadBytes} bytes");
  • 힙 메모리 크기, 사용량, 할당률 확인.
  • 애플리케이션 메모리 문제를 사전에 진단.

LatencyMode

GC의 대기 모드를 확인하거나 변경할 수 있습니다.

  • 대기 모드 종류
    • Batch: 최적의 처리량을 위해 GC를 배치 모드로 실행.
    • Interactive: 사용자 상호작용이 많은 애플리케이션에 적합.
    • SustainedLowLatency: 짧은 지연 시간을 요구하는 작업에 적합.
Console.WriteLine($"Current Latency Mode: {GCSettings.LatencyMode}");
GCSettings.LatencyMode = GCLatencyMode.SustainedLowLatency;
Console.WriteLine($"Updated Latency Mode: {GCSettings.LatencyMode}");
  • 실시간 작업(예: UI 렌더링)에서 GC 중단 최소화.
  • 배치 처리 시스템에서 처리량 극대화.

AddMemoryPressure / RemoveMemoryPressure

GC가 비관리 메모리 사용량을 더 정확히 추적할 수 있도록 메모리 사용을 알립니다.

GC.AddMemoryPressure(1024 * 1024); // 1MB 메모리 사용 추가
GC.RemoveMemoryPressure(1024 * 1024); // 1MB 메모리 사용 제거
  • 비관리 리소스(예: 네이티브 라이브러리)를 사용하는 경우 GC와의 메모리 관리 조정.

간단한 GC 모니터링 코드 예제

using System;

class Program
{
    static void Main()
    {
        Console.WriteLine("GC Monitoring Example:");

        // 현재 메모리 사용량
        long memoryUsed = GC.GetTotalMemory(false);
        Console.WriteLine($"Total Memory: {memoryUsed} bytes");

        // 세대별 GC 수집 횟수
        for (int gen = 0; gen <= GC.MaxGeneration; gen++)
        {
            Console.WriteLine($"Gen {gen} Collections: {GC.CollectionCount(gen)}");
        }

        // 힙 메모리 정보
        var memoryInfo = GC.GetGCMemoryInfo();
        Console.WriteLine($"Heap Size: {memoryInfo.HeapSizeBytes} bytes");
        Console.WriteLine($"Total Available Memory: {memoryInfo.TotalAvailableMemoryBytes} bytes");

        // GC 대기 모드 확인 및 설정
        Console.WriteLine($"Latency Mode: {GCSettings.LatencyMode}");
        GCSettings.LatencyMode = GCLatencyMode.Interactive;
        Console.WriteLine($"Updated Latency Mode: {GCSettings.LatencyMode}");
    }
}