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}");
}
}