2009-03-10 13 views
5

Ho familiarità con WeakReference, ma sto cercando un tipo di riferimento che viene cancellato solo quando la memoria è bassa, non semplicemente ogni volta che gc viene eseguito (proprio come Java SoftReference). Sto cercando un modo per implementare una cache sensibile alla memoria.Equivalente a SoftReference in .net?

risposta

0

No, non esiste un equivalente. C'è un motivo particolare per cui lo WeakReference non farà il lavoro?

Ecco una domanda simile al vostro:

Why doesn't .NET have a SoftReference as well as a WeakReference, like Java?

+3

-1 Tony ha detto che voleva implementare un cache sensibile alla memoria. Eppure MSDN lo dice su WeakReferences: "Evita di utilizzare riferimenti deboli come soluzione automatica ai problemi di gestione della memoria, ma sviluppa una politica di caching efficace per la gestione degli oggetti dell'applicazione". –

2

La cache di ASP.NET vi dà il comportamento della memoria sensibile che si desidera, con l'inconveniente che tutto ha bisogno di una chiave univoca. Tuttavia, dovresti essere in grado di mantenere un WeakReference su un oggetto che hai inserito nella cache di ASP.NET. Il riferimento forte della cache manterrà il GC a bada finché la cache non deciderà che deve essere scavato per liberare memoria. WeakReference ti dà accesso all'oggetto senza fare una ricerca con la chiave di cache.

Foo cachedData = new Foo(); 
WeakReference weakRef = new WeakReference(cachedData); 
HttpRuntime.Cache[Guid.NewGuid().ToString()] = cachedData; 

... 

if (weakRef.IsAlive) 
{ 
    Foo strongRef = weakRef.Target as Foo; 
} 

è possibile creare una classe SoftReference estendendo WeakReference lungo le linee di

class SoftReference : WeakReference 
{ 
    public SoftReference(object target) : base(target) 
    { 
     HttpRuntime.Cache[Guid.NewGuid().ToString()] = target; 
    } 
} 

Faresti inoltre necessario eseguire l'override del setter sulla strada giusta per fare in modo che qualsiasi nuovo obiettivo va nella cache.

1

Sebbene un SoftReference possa sembrare un modo conveniente per implementare il caching della memoria, richiede al runtime Java di determinare in modo un po 'arbitrario se il vantaggio di mantenere un oggetto intorno superi il costo di memorizzarlo. Sfortunatamente, il runtime ha informazioni limitate sul costo reale della conservazione di un oggetto (tenendo presente che il costo reale può comprendere l'impatto dell'utilizzo della memoria di un'applicazione su altre applicazioni) e praticamente nessuna informazione sul vantaggio di mantenere l'oggetto intorno .

Se vale la pena di tenere un oggetto intorno anche quando non ci sono forti riferimenti esterni a esso, una cache dovrebbe mantenere un forte riferimento ad esso (almeno finché sembra degna). Se il vantaggio di mantenere l'oggetto nella cache si estenderà solo finché esiste un riferimento esterno (ad esempio perché la produzione di istanze è economica, ma l'esistenza di due entità logiche che contengono dati identici utilizzano la stessa istanza per trattenerli faciliterebbe il confronto tra tali entità), si dovrebbe usare uno WeakReference.

Per inciso, se avessi i miei druthers,.net supporterà un altro tipo di riferimento che non ho visto in nessuna piattaforma: un riferimento "di interesse per qualcun altro", che verrebbe utilizzato in combinazione con un tipo di WeakReference. Un riferimento "di interesse per qualcun altro" potrebbe essere usato come riferimento forte, ma uno WeakReference opportunamente configurato sarebbe invalidato se gli unici riferimenti forti al suo target fossero "di interesse per qualcun altro". Un tale concetto potrebbe migliorare l'efficienza quando si utilizza un GC concorrente, nei casi in cui un gestore di eventi deboli genererebbe ripetutamente un riferimento forte al proprio target. Se nessuno è realmente interessato a ciò che il gestore di eventi sta facendo con il suo obiettivo, sarebbe auspicabile che il gestore potesse ottenere l'annullamento della sottoscrizione.