Suche…


Große Objekthaufenverdichtung

Standardmäßig wird der Large Object Heap nicht komprimiert, im Gegensatz zum klassischen Object Heap, der zu einer Fragmentierung des Speichers und darüber hinaus zu OutOfMemoryException s führen kann

Ab .NET 4.5.1 besteht die Möglichkeit , den Large Object Heap (zusammen mit einer Garbage Collection) explizit zu komprimieren:

GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect();   

Genauso wie jede explizite Garbage-Collection-Anforderung (diese wird als Anforderung bezeichnet, weil die CLR nicht dazu gezwungen ist, sie auszuführen), wird diese mit Vorsicht verwendet und standardmäßig vermieden, wenn dies möglich ist, da GC Statistiken deaktiviert werden können, was deren Leistung beeinträchtigt.

Schwache Referenzen

In .NET ordnet der GC Objekte zu, wenn keine Referenzen mehr vorhanden sind. Daher kann der GC dieses Objekt nicht zuweisen, obwohl ein Objekt immer noch über Code erreichbar ist (es gibt einen starken Verweis darauf). Dies kann zu einem Problem werden, wenn viele große Objekte vorhanden sind.

Eine schwache Referenz ist eine Referenz, die es dem GC ermöglicht, das Objekt zu erfassen und gleichzeitig auf das Objekt zuzugreifen. Eine schwache Referenz gilt nur während der unbestimmten Zeit, bis das Objekt erfasst wird, wenn keine starken Referenzen vorhanden sind. Wenn Sie eine schwache Referenz verwenden, kann die Anwendung immer noch eine starke Referenz auf das Objekt erhalten, wodurch verhindert wird, dass es erfasst wird. Schwache Referenzen können daher nützlich sein, um große Objekte festzuhalten, deren Initialisierung teuer ist, die aber für die Speicherbereinigung zur Verfügung stehen sollten, wenn sie nicht aktiv verwendet werden.

Einfache Verwendung:

WeakReference reference = new WeakReference(new object(), false);

GC.Collect();

object target = reference.Target;
if (target != null)
  DoSomething(target);

So könnten schwache Referenzen verwendet werden, um beispielsweise einen Cache von Objekten zu verwalten. Es ist jedoch wichtig zu wissen, dass immer die Gefahr besteht, dass der Speicherbereiniger das Objekt erreicht, bevor eine starke Referenz erstellt wird.

Schwache Referenzen sind auch hilfreich, um Speicherlecks zu vermeiden. Ein typischer Anwendungsfall betrifft Ereignisse.

Angenommen, wir haben einen Handler für ein Ereignis in einer Quelle:

Source.Event += new EventHandler(Handler)

Dieser Code registriert einen Ereignishandler und erstellt eine starke Referenz von der Ereignisquelle auf das empfangende Objekt. Wenn das Quellobjekt eine längere Lebensdauer als der Listener hat und der Listener das Ereignis nicht mehr benötigt, wenn keine anderen Verweise darauf vorhanden sind, führt die Verwendung normaler .NET-Ereignisse zu einem Speicherverlust: Das Quellobjekt enthält Listener-Objekte im Speicher sollte Müll gesammelt werden.

In diesem Fall empfiehlt es sich, das Weak Event Pattern zu verwenden .

So etwas wie:

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

und so verwendet:

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

In diesem Fall haben wir natürlich einige Einschränkungen - die Veranstaltung muss eine sein

public event EventHandler<SomeEventArgs> Event;

Wie MSDN vorschlägt:

  • Verwenden Sie lange, schwache Referenzen nur, wenn dies erforderlich ist, da der Status des Objekts nach der Fertigstellung nicht vorhersagbar ist.
  • Vermeiden Sie die Verwendung schwacher Verweise auf kleine Objekte, da der Zeiger selbst so groß oder größer sein kann.
  • Vermeiden Sie die Verwendung schwacher Verweise als automatische Lösung für Probleme bei der Speicherverwaltung. Entwickeln Sie stattdessen eine effektive Caching-Richtlinie für die Handhabung der Objekte Ihrer Anwendung.


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow