Sök…


Komprimering av stor objekthög

Som standard komprimeras inte Large Object Heap till skillnad från den klassiska Object Heap som kan leda till minnesfragmentering och vidare kan leda till OutOfMemoryException s

Från och med .NET 4.5.1 finns det ett alternativ att uttryckligen kompaktera Large Object Heap (tillsammans med en skräpkollektion):

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

Precis som varje uttrycklig begäran om avfallsuppsamling (det kallas förfrågan eftersom CLR inte är tvungen att genomföra den) används med försiktighet och undvik den som standard om du kan eftersom den kan de-kalibrera GC s statistik, vilket minskar dess prestanda.

Svaga referenser

I .NET tilldelar GC objekt när det inte finns några referenser kvar till dem. Därför, medan ett objekt fortfarande kan nås från koden (det finns en stark referens till det), kommer GC inte att tilldela detta objekt. Detta kan bli ett problem om det finns många stora föremål.

En svag referens är en referens som gör att GC kan samla objektet medan det fortfarande tillåter åtkomst till objektet. En svag referens gäller endast under obestämd tid tills objektet samlas in när inga starka referenser finns. När du använder en svag referens kan applikationen fortfarande få en stark referens till objektet, vilket förhindrar att det samlas in. Så svaga referenser kan vara användbara för att hålla fast vid stora föremål som är dyra att initiera, men borde vara tillgängliga för skräpsamling om de inte aktivt används.

Enkel användning:

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

GC.Collect();

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

Så svaga referenser kan användas för att till exempel upprätthålla en cache av objekt. Det är emellertid viktigt att komma ihåg att det alltid finns risken att sopor samlaren kommer till objektet innan en stark referens återupprättas.

Svaga referenser är också praktiska för att undvika minnesläckor. Ett typiskt fall är med händelser.

Anta att vi har någon hanterare till en händelse på en källa:

Source.Event += new EventHandler(Handler)

Denna kod registrerar en händelsehanterare och skapar en stark referens från händelsekällan till lyssnarobjektet. Om källobjektet har en längre livslängd än lyssnaren och lyssnaren inte behöver händelsen längre när det inte finns några andra referenser till det, använder normala .NET-händelser ett minnesläckage: källobjektet håller lyssnarobjekt i minnet som bör skräp samlas in.

I det här fallet kan det vara en bra idé att använda det svaga händelsemönstret .

Något liknande:

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

och använde så här:

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

I detta fall har vi naturligtvis vissa begränsningar - händelsen måste vara en

public event EventHandler<SomeEventArgs> Event;

Som MSDN antyder:

  • Använd långa svaga referenser endast när det är nödvändigt eftersom objektets tillstånd är oförutsägbart efter slutförandet.
  • Undvik att använda svaga referenser till små objekt eftersom pekaren själv kan vara lika stor eller större.
  • Undvik att använda svaga referenser som en automatisk lösning på minneshanteringsproblem. Istället utvecklar du en effektiv cachepolicy för att hantera din applikations objekt.


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow