2016-08-19 1 views
0

I in Tests bemerkt, dass mehrere Anrufe zu dem folgenden Code einen Speicherverlust erzeugt:Wie kann ich eine Baugruppe freigeben, nachdem ich sie mit Reflektion geladen habe?

object obj = Activator.CreateInstance(Type.GetType(arg2.DeclaringType.FullName)); 
arg2.Invoke(obj, new object[] { arg3 }); 

Für den obigen Code, arg2 ist MethodInfo Typ; arg3 ist string[]

Auch wenn ich obj = null; nach dem Invoke hinzufügen, es scheint, dass GAC dieses Objekt nicht für die Bereinigung sammeln. (Ja, ich weiß, dass das Setzen eines Objekts auf null eine schlechte Entschuldigung für dispose() ist, da es sich jedoch um eine generische Methode handelt, kann displace() in der Klasse verfügbar sein oder nicht und mit Assemblys getestet werden, die über dispose verfügen (sie werden nach der Verwendung nicht entladen)

Ich habe in Erwägung gezogen, einen Cache-Mechanismus zu verwenden, bei dem die geladene Assembly in einem Wörterbuch für nachfolgende Suchvorgänge gespeichert wird. Es gibt jedoch keine Garantie, dass GAC nicht kommt und es später aufräumt Objekt im Wörterbuch unbrauchbar (unter anderen Katastrophen).

Wie kann ich ein Entladen der Klasse erzwingen (ähnlich wie ich es erzwingen kann, indem ich Activate laden), wenn ich damit fertig bin?

+1

Möchten Sie jetzt eine Assembly in der AppDomain freigeben oder eine Instanz eines Objekts entfernen? Sie sind Titel und Text sind irreführend – Mark

+1

'obj = null' ist im Allgemeinen sinnlos für eine lokale Variable. Der JIT und der GC arbeiten zusammen, um die Lebensdauer der Referenz zu "verstehen", und sobald kein anderer Teil des Codes * von obj liest, wird das Objekt, auf das es Bezug nimmt, nicht mehr gespeichert. Keine Hilfe von Ihnen ist erforderlich. –

+0

@Damien_The_Unbeliever - Ich sollte wahrscheinlich ein wenig über meine Tests klären. Ich habe die Benutzeroberfläche geöffnet und die Aktion ausgeführt, die den obigen Code (click event) mehrfach aufgerufen hat. Mit jedem Klick wurde die Speichernutzung erhöht. Ich konnte es gehen lassen (langsam) von 36MB bis 100MB verwendet nach mehreren Klicks. Die einzige Aktion, die der Klick ausführt, ist das Laden dieser Assembly, das Spiegeln der Methode und das Beenden. –

Antwort

1

Lassen Sie uns das gerade, you can not unload an assembly when it has been loaded unless you unload the entire Application Domain.

(und wenn Sie wissen wollen, warum: check this blog)

jedoch mit einer Klasse ist es anders, Sie sprechen es aus dem Speicher freigibt. Sind Sie sicher, dass kein anderes Objekt Zugriff darauf hat?

Wenn Sie sich sicher sind, wissen, dass der Garbage Collector die Erinnerung an die nicht referenzierte Objekte freigeben, wann immer es will, so etwa Speicherverlust sprechen könnte ein bisschen prematured werden ...

Sie können jedoch force the Garbage Collector to clean up the memory by calling GC.Collect()

+0

Ich werde versuchen, GC zu erzwingen, aber wie Sie gesagt haben, muss ich möglicherweise warten, bis die Anwendung entscheidet, dass es nicht mehr verwendet wird, um es trotzdem zu bereinigen - oder einfach die Klasse zwischenspeichern, da es zu sein scheint irgendwie auf unbestimmte Zeit stecken geblieben, um zu verhindern, dass es mehr als einmal geladen wird. –

Verwandte Themen