C# Language
.NET의 가비지 수집기
수색…
대형 객체 힙 압축
기본적으로 Large Object Heap은 메모리 조각화로 이어질 수 있는 고전적인 Object Heap과 달리 압축되지 않으며 OutOfMemoryException
이어질 수 있습니다.
.NET 4.5.1부터는 가비지 수집과 함께 Large Object Heap을 명시 적으로 압축 하는 옵션 이 있습니다.
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect();
명시 적 가비지 수집 요청 (CLR이 강제로 수행하지 않으므로 요청이라고 함)과 마찬가지로주의를 기울여 사용하고 기본적으로 GC
의 통계를 교정하여 성능을 저하시킬 수 있으므로 가능한 경우 사용하지 마십시오.
약한 참조
.NET에서 GC는 객체에 대한 참조가 없을 때 객체를 할당합니다. 따라서 코드에서 오브젝트에 계속 도달 할 수 있지만 (강력한 참조가 있음) GC는이 오브젝트를 할당하지 않습니다. 대형 객체가 많은 경우 문제가 될 수 있습니다.
약한 참조는 GC가 객체를 액세스 할 수 있도록하면서 객체를 수집 할 수 있도록하는 참조입니다. 약한 참조는 강한 참조가 없을 때 객체가 수집 될 때까지 불확실한 시간 동안 만 유효합니다. 약한 참조를 사용하면 응용 프로그램에서 개체에 대한 강력한 참조를 얻을 수 있으므로 개체가 수집되지 않습니다. 따라서 weak 참조는 초기화에 비용이 많이 드는 대형 객체를 고정하는 데 유용 할 수 있지만 사용하지 않는 경우 가비지 수집을 위해 사용할 수 있어야합니다.
간단한 사용법 :
WeakReference reference = new WeakReference(new object(), false);
GC.Collect();
object target = reference.Target;
if (target != null)
DoSomething(target);
따라서 약한 참조를 사용하여 예를 들어 객체의 캐시를 유지할 수 있습니다. 그러나 강력한 참조가 다시 설정되기 전에 가비지 수집기가 개체에 도달 할 위험이 항상 있음을 기억하는 것이 중요합니다.
약한 참조는 메모리 누수를 피할 때도 유용합니다. 일반적인 사용 사례는 이벤트입니다.
소스에 이벤트에 대한 처리기가 있다고 가정합니다.
Source.Event += new EventHandler(Handler)
이 코드는 이벤트 핸들러를 등록하고 이벤트 소스에서 수신 대기중인 객체에 대한 강력한 참조를 만듭니다. 소스 객체가 리스너보다 수명이 길고 리스너에 다른 참조가 없을 때 리스너가 이벤트를 더 이상 필요로하지 않으면 일반 .NET 이벤트를 사용하면 메모리 누수가 발생합니다. 소스 객체는 메모리에있는 리스너 객체를 보유합니다. 쓰레기 수거해야합니다.
이 경우 약한 이벤트 패턴 을 사용하는 것이 좋습니다.
같은 것 :
public static class WeakEventManager
{
public static void SetHandler<S, TArgs>(
Action<EventHandler<TArgs>> add,
Action<EventHandler<TArgs>> remove,
S subscriber,
Action<S, TArgs> action)
where TArgs : EventArgs
where S : class
{
var subscrWeakRef = new WeakReference(subscriber);
EventHandler<TArgs> handler = null;
handler = (s, e) =>
{
var subscrStrongRef = subscrWeakRef.Target as S;
if (subscrStrongRef != null)
{
action(subscrStrongRef, e);
}
else
{
remove(handler);
handler = null;
}
};
add(handler);
}
}
그리고 이렇게 사용 :
EventSource s = new EventSource();
Subscriber subscriber = new Subscriber();
WeakEventManager.SetHandler<Subscriber, SomeEventArgs>(a => s.Event += a, r => s.Event -= r, subscriber, (s,e) => { s.HandleEvent(e); });
이 경우에는 몇 가지 제한이 있습니다. 이벤트는
public event EventHandler<SomeEventArgs> Event;
MSDN에서 제안하는대로 :
- 완료 후 객체 상태가 예측할 수없는 경우에만 필요하면 긴 weak 참조를 사용하십시오.
- 포인터 자체가 크거나 클 수 있으므로 약한 참조를 사용하지 마십시오.
- 약한 참조를 메모리 관리 문제에 대한 자동 해결책으로 사용하지 마십시오. 대신 응용 프로그램의 객체를 처리하기위한 효과적인 캐싱 정책을 개발하십시오.