| 

.NET C# Java Javascript Exception

1
Schönen guten Tag,

meine Frage betrifft die Speicherfreigabe unter VB.NET mit FW 2.0 und 4.0

Als Annahme sei folgende einfache Objektstruktur deklariert:

Public Class Rack
   Public Name As String
   Public Number As Integer
   Public Shelves As Dictionary(Of String, Shelf)
End Class

Public Class Shelf
   Public Name As String
   Public Number As Integer
   Public Books As Dictionary(Of String, Book)
End Class

Public Class Book
   Public Name As String
   Public Number As Integer
   Public Chapters As Dictionary(Of String, Chapter)
End Class

Public Class Chapter
   Public Name As String
   Public Number As Integer
   Public Pages As Dictionary(Of String, Page)
End Class

Public Class Page
   Public Number As Integer
   Public Contents As String
End Class

Der Aufruf einer Funktion GetRackContents(Name As String) As Rack liefert mir nun den Inhalt des gewünschten Racks zB im Objekt myRack zurück - myRack enthält dann viele Shelves, die noch mehr Bücher, Kapitel und Seiten enthalten. Gut soweit.

Wenn nun die Verwendung von myRack abgeschlossen ist und ich das Objekt nicht mehr brauche, was ist dann tatsächlich zu tun, um den Speicher (inklusive aller untergeordneter Objekte) wieder freizugeben? Sollte ich
a.) myRack durch Verlassen seiner Deklarationsumgebung einfach out of scope gehen lassen - die GC macht dann schon alles nötige
b.) myRack vor Verlassen seiner Deklarationsumgebung zumindest auf Nothing setzen
c.) zumindest die in den einzelnen Objekten enthaltenen Dictionaries mit .Clear() leeren
d.) vor dem Leeren der in den einzelnen Objekten enthaltenen Dictionaries explizit auch die enthaltenen Objekt auf Nothing setzen

Meine Vermutung: richtig ist Antwort "a". Alles andere ist zwar nicht falsch, ist aber genau genommen unnötig und kostet vor allem Prozessorzeit. Aber ich würde es gerne genau wissen, und so bitte ich um Antwort von jemanden, der es wirklich weiß!

Vielen Dank vorab schon aus dem strahlend sonnigen Wien,
Robert ;-)
09.03.2012
Robert 57 1 6
2 Antworten
0
a.) Ja. Wenn keine Referenzen mehr auf das Objekt vorhanden sind, wird es irgendwann vom GC entfernt. Wenn es keine sonstigen Referenzen auf die Elemente im Dictionary gibt, werden diese auch collected.
b.) Was soll das bringen?
c.) siehe b.
d.) siehe c.

<rant>Irgendwelche lokalen Variablen auf Nothing setzen unmittelbar bevor diese out of scope gehen ist so eine Unart, die VB6 Programmierer immer in VB.Net machen...</rant>
09.03.2012
dkson 44 1
Danke für's Feedback! Wie du richtig vermutest ist das eine Unart, die sich aus (sehr) alten VB6 Tagen erhalten hat (wo das aber teilweise wirklich sehr wichtig war)
Robert 09.03.2012
1
Das Problem ist das "irgendwann vom GC entfernt" ...

Ich habe die Erfahrung gemacht, dass gerade bei großen Anwendungen mit vielen Formularen, der Garbage Collector einfach zu spät aufräumt und die Anwendung zu "fett" wird.

Ein gezieltes GC.Collect wirkt hier wahre Wunder.


mblaess 09.03.2012
1
Wir die Klasse komplexer um nutzt zum Beispiel Fremdkomponenten / Handler solltest Du dringend in deinem Objekt aufrufen lassen. Dazu einfach selbst Dispose implementieren und aufräumen. Es gibt hier andere Threads in denen einem klar wird, was passieren kann wenn man sich darauf verlässt das der GC alles alleine geregelt bekommt wenn die Objekte OOS laufen.
Slashi 10.03.2012
-mblaess: Danke für den Hinweis, aber nach Lesen diverser Beiträge zur GC scheue ich die Verwendung von .Collect: die Konklusio dieser Artikel ist durchgängig die, dass man das Framwork lieber selber Ordnung halten lassen soll wenn man sich nicht wirklich gut mit dessen Mechanismen auskennt, da man sonst leicht Objekte in die 2te Generationen bugsiert und sich so schnell ein Speicherproblem an anderer Stelle eröffnet...
Robert 12.03.2012
@Robert: Wenn Du steuern willst wann der Speicher wieder freigegeben wird, bleibt Dir nur der Aufruf von GC.Collect(). Genau dazu kann man diese Funktion überhaupt aufrufen. Es gibt diverse Scenarien wo man den manuellen Aufruf benötigt.
Slashi 12.03.2012
0
Beachte, dass deine Methode üblicherweise lediglich eine flache Kopie eines Racks zurück gibt. Der Speicherverbrauch für den Verweis ist zu vernachlässigen.
11.03.2012
Wolfgang R. 61 3
Hallo Wolfgang, darf ich nachfragen wie du das genau meinst? Der Verweis auf das Rootergebnis "Rack" braucht natürlich kaum Speicher (4 Byte auf einem 32 Bit System), mit allen Subverweisen auf Details summiert sich aber der Bedarf: wenn das Rack nur 100 Shelves mit jeweils 100 Books und jeweils 100 Chapters mit jeweils 100 Pages enthält habe ich schon 100.000.000 Detail-Objektverweise (ca. 400 MB), plus 1.010.101 Dictionary-Verweise (ca. 4 MB), d.h. ca. 404 MB OHNE der eigentlichen Detaildaten... und dieser Speicher sollte natürlich asap nach Verwendung wieder als verfügbar erkannt werden.
Robert 12.03.2012
Hi Robert,
du solltest auch mal drüber nachdenken, ob es wirklich notwendig ist, diese Menge an Daten überhaupt in den Speicher zu ziehen. Es gibt viele Alternativen, die hier helfen könnten, z.B. eine Datenbank, ein eigener Filecontainer (z.b. über MemoryMappedFile), ...
Ein User Deines Tools würde von dieser Datenflut sicher auch erschlagen werden. Normalerweise betrachten User immer nur Teile der Daten gleichzeitig und eine Navigation in der Gesamtmenge kann man auch anders erreichen, als die Struktur komplett im Speicher aufzubauen.

ffordermaier 12.03.2012
@ffordermaier: natürlich hast du Recht und die Bearbeitung einer solchen Datenmenge ist ja gar nicht mein Anliegen - das war lediglich ein Beispiel, um meiner Frage über Speicherfreigabe von Objekten (die weitere verschachtelte Verweise enthalten) einen Rahmen zu geben.
Robert 12.03.2012
@Robert: Ah, ok, hab Deinen Kommentar wohl falsch interpretiert...
ffordermaier 12.03.2012

Stelle deine .net-Frage jetzt!
TOP TECHNOLOGIES CONSULTING GmbH