Ich lese immer, dass es empfehlenswert ist, Objekte auf Null zu setzen, sobald ich mit ihnen fertig bin. Normalerweise verwende ich sie nur in Funktionen innerhalb von Formularen.
Ist der Verweis nicht verloren und wird der Speicher freigegeben, wenn der Funktionsumfang verlassen wird, unabhängig davon, ob Objekte auf Nothing gesetzt werden?
ist es wirklich notwendig zu tun:
Set db = Nothing
Set record_set = Nothing
VB verwendet einen sogenannten "Referenzzähler" - Garbage Collection.
Grundsätzlich wird in dem Moment, in dem eine Variable den Gültigkeitsbereich verlässt, der Referenzzähler für das referenzierte Objekt dekrementiert. Wenn Sie die Objektreferenz einer anderen Variablen zuweisen, wird der Referenzzähler inkrementiert.
Wenn der Zähler Null erreicht, ist das Objekt zur Speicherbereinigung bereit. Die Objektressourcen werden freigegeben, sobald dies geschieht. Eine lokale Funktionsvariable referenziert höchstwahrscheinlich ein Objekt, dessen Referenzwert niemals höher als 1 wird. Objektressourcen werden daher freigegeben, wenn die Funktion endet.
Wenn Sie eine Variable auf Nothing
setzen, können Sie den Referenzzähler explizit verringern.
Beispielsweise lesen Sie eine Datei ein und setzen die Dateiobjektvariable gleich nach dem Aufruf von ReadAll()
auf Nothing
. Das Dateihandle wird sofort freigegeben, Sie können sich Zeit lassen, um den Inhalt zu verarbeiten.
Wenn Sie nicht auf Nothing
setzen, ist der Datei-Handle möglicherweise länger geöffnet als unbedingt erforderlich.
Wenn Sie sich nicht in einer Situation befinden, in der Sie "eine wertvolle Ressource entsperren müssen", ist es in Ordnung, die Variablen einfach aus dem Geltungsbereich gehen zu lassen.
Die Müllabfuhr ist selten perfekt. Selbst in .NET gibt es Zeiten, in denen Sie nachdrücklich aufgefordert werden, das System frühzeitig zur Speicherbereinigung aufzufordern.
Aus diesem Grund habe ich explizit sowohl close als auch Nothing Recordsets gesetzt, wenn ich mit ihnen fertig bin.
Die letzte Zeile des Hilfethemas für " Recordset.Close " in der Microsoft DAO-Hilfe und der Access Developer Reference lautet:
"Eine Alternative zur Close-Methode ist , Um den Wert einer Objektvariablen Auf Nothing (Set dbsTemp = Nothing) zu setzen."
http://msdn.Microsoft.com/de-de/library/bb243098.aspx
Aus diesem Grund werden Sie in this article aus der Microsoft Knowledge Base mit dem Titel "Datenbankaufblähung nach Verwendung von Data Access Objects (DAO) verhindern" empfohlen, dass Sie explizit schließen sollten, wenn Ihre Datenbanken nicht gewünscht werden aufblasen Sie werden feststellen, dass der Artikel bezüglich der Details etwas vage ist; Der Abschnitt "Ursache" ist unklar, fast bis zum Kauderwelsch.
http://support.Microsoft.com/kb/289562
Problembeschreibung: Eine Microsoft Access-Datenbank hat mit dem Aufblähen begonnen (oder wächst schnell in Größe), nachdem Sie Data Access implementiert haben Objekte (DAO) zum Öffnen eines Recordset.
URSACHE: Wenn Sie eine .__ nicht freigeben. Recordset-Speicher jedes Mal, wenn Sie Durchlaufen Sie den Recordset-Code DAO kann mit mehr Arbeitsspeicher und .__ erneut kompilieren. die Größe der Datenbank erhöhen.
Weitere Informationen: Wenn Sie eine .__ erstellen. Recordset (oder ein QueryDef) Objekt in Code, schließen Sie das Objekt explizit, wenn Du bist fertig. Microsoft Access schließt automatisch Recordset und QueryDef-Objekte unter den meisten Umstände. Wenn Sie jedoch Schließen Sie das Objekt explizit in Ihrer Code können Sie gelegentlich vermeiden Fälle, in denen das Objekt bestehen bleibt öffnen.
Abschließend möchte ich noch hinzufügen, dass ich seit 15 Jahren mit Access-Datenbanken arbeite und meine lokal deklarierten Recordset-Variablen fast immer außer Reichweite ließe, ohne die Close-Methode explizit zu verwenden. Ich habe es noch nicht getestet, aber es scheint keine Rolle zu spielen.
Wenn Sie ASP classic (serverseitige Skripterstellung) verwenden, müssen beim Import alle Objekte auf null gesetzt werden, wenn Sie mit ihnen fertig sind, da sie sich erst nach dem Herunterfahren des [virtuellen] Servers aus dem Gültigkeitsbereich entfernen .
Aus diesem Grund wurden in allen MS VB -Skriptionsbeispielen immer Objekte geschlossen und auf nichts gesetzt. Damit die Skriptauszüge in Umgebungen wie ASP classic verwendet werden können, in denen die Objekte nicht außerhalb des Gültigkeitsbereichs liegen.
Es gibt in seltenen Fällen andere Situationen, in denen Sie lang laufende Prozesse codieren möchten, bei denen die Objekte nicht außerhalb des Gültigkeitsbereichs liegen, und der physische Speicher knapp wird, wenn Sie Objekte nicht explizit freigeben.
Wenn Sie ASP klassisch kodieren oder aus einem anderen Grund Prozesse im globalen Bereich ausführen, sollten Sie ja explizit Objekte freigeben.
Referenzen sollten bereinigt werden, wenn die Variable den Gültigkeitsbereich verlässt. Vermutlich hat sich dies mit späteren Versionen der Software verbessert, war jedoch auf einmal nicht zuverlässig. Ich glaube, dass es eine gute Praxis bleibt, Variablen explizit auf "Nothing" zu setzen.
Normalerweise setze ich dies immer am Ende meiner Prozeduren ein oder rufe ein "CloseRecordSet" -Unter mit auf, wenn ich Modulebene-Ebenen verwende:
Private Sub Rawr()
On Error GoTo ErrorHandler
'Procedural Code Here.
ExitPoint:
'Closes and Destroys RecordSet Objects.
If Not Recset Is Nothing Then
If Recset.State = 1 Then
Recset.Close
Conn.Close
End If
Set Recset = Nothing
Set Conn = Nothing
End If
Exit Sub
ErrorHandler:
'Error Handling / Reporting Here.
Resume ExitPoint
End Sub
Auf diese Weise endet jedoch die Prozedur (normal oder aufgrund eines Fehlers), die Objekte werden bereinigt und die Ressourcen sind frei.
Wenn Sie dies auf diese Weise tun, ist dies ziemlich sicher, da Sie es einfach einhaken können und nur das Nötige tun werden, um das Recordset/Verbindungsobjekt zu schließen oder zu zerstören, falls es bereits geschlossen wurde (aufgrund eines Laufzeitfehlers oder Schließen Sie es einfach, so wie Sie es sollten.
Es ist wirklich nicht viel Aufwand und es ist immer am besten, Ihre Objekte zu bereinigen, wenn Sie damit fertig sind, um sofort Ressourcen freizusetzen, unabhängig davon, was im Programm passiert.