수색…


대형 객체 힙 압축

기본적으로 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 참조를 사용하십시오.
  • 포인터 자체가 크거나 클 수 있으므로 약한 참조를 사용하지 마십시오.
  • 약한 참조를 메모리 관리 문제에 대한 자동 해결책으로 사용하지 마십시오. 대신 응용 프로그램의 객체를 처리하기위한 효과적인 캐싱 정책을 개발하십시오.


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow