3 Stimmen

Was ist der Sinn des Garbage Collectors?

SqlConnection connection = new SqlConnection(FROM_CONFIGURATION) 
SqlCommand command = new SqlCommand("SomeSQL", connection); 
connection.Open(); 
command.ExecuteNonQuery(); 
command.Dispose(); 
connection.Dispose();

Es wird empfohlen, dass der obige Code try/catch (oder using) enthält, damit im Falle einer Ausnahme alle Ressourcen ordnungsgemäß entsorgt werden.

Aber wenn man sich um die manuelle Entsorgung kümmern muss, was ist dann der Sinn der GC?! Ist GC nicht dazu da, dies für den Programmierer zu erledigen?

3voto

IAmCodeMonkey Punkte 1580

Die GC läuft gelegentlich und kümmert sich um die Speicherverwaltung, damit alles schön ordentlich bleibt. Wenn Sie Codefragmente wie das von Ihnen gepostete sehen, denken Sie vielleicht, dass es nutzlos ist, aber in den meisten Fällen erspart es Ihnen eine Menge Kopfschmerzen (denken Sie an die manuelle Speicherverwaltung in C/C++), da es Speicherlecks stark reduziert und Sie sich darum kümmern können, wie Ihre Anwendung läuft und nicht, wie Sie den Speicher verwalten. Die Beseitigung von Datei-Handles und Datenbankverbindungen ist ein Weg, die Effizienz zu steigern, da die Garbage Collection nicht deterministisch ist und möglicherweise nicht sofort erfolgt, und Sie wollen nicht, dass diese Datei-Handles und offenen Datenbankverbindungen die Leistung Ihres Systems beeinträchtigen. Btw, Ihr Code ist wirklich hässlich, ich befürworte immer die using-Anweisung und schreibe häufig meine db-Code wie diese:

using (SqlConnection connection = new SqlConnection(...))
using (SqlCommand command = connection.CreateCommand())
{
   ...
}

Dies ruft automatisch dispose für die Verbindungs- und Befehlsobjekte auf, wenn sie aus dem Anwendungsbereich fallen, d. h. wenn die Ausführung den Block verlässt.

2voto

Kon Punkte 26399

Denn GC ist nicht die effizienteste Methode - sie wird nicht immer sofort ausgeführt, wenn die Ressource nicht mehr verwendet wird. Wenn Sie also mit nicht verwalteten Ressourcen wie Datei-I/O, DB-Verbindungen usw. zu tun haben, ist es am besten, diese Ressourcen freizugeben/aufzuräumen, bevor Sie warten und sich darauf verlassen, dass GC sich darum kümmert.

Und prüfen Sie die Verwendung des using Stichwort:

using (SqlConnection connection = new SqlConnection(FROM_CONFIGURATION))
using (SqlCommand command = new SqlCommand("SomeSQL", connection))
{
  connection.Open(); 
  command.ExecuteNonQuery(); 
  command.Dispose(); 
  connection.Dispose();
}

Außerdem sollte alles, was entsorgt werden kann, in der Regel in einem using Block.

2voto

Mr Fooz Punkte 102791

...Die GC war nie dazu gedacht, Ressourcen zu verwalten; sie wurde entwickelt, um die Speicherzuweisung zu verwalten ... Im speziellen Fall von Datenbankverbindungen geht es um andere Ressourcen als nur um Speicher... (Scott Dorman)

Der OP hat keine bestimmte Plattform angegeben, obwohl die meisten Antworten .net-spezifisch sind und darauf hinweisen, dass GC hauptsächlich zur Vermeidung von Speicherlecks dient, aber Erweiterungen wie using Ausdrücke und IDisposable kann sehr hilfreich sein.

Andere Plattformen bieten andere Lösungen. In C++ gibt es beispielsweise keine (eingebaute) Garbage Collection, aber einige Formen von gemeinsam genutzten Zeigern können bei der Speicherverwaltung helfen, und der RAII-Stil der Codierung kann bei der Verwaltung anderer Arten von Ressourcen äußerst hilfreich sein.

In cPython werden zwei verschiedene Garbage-Collection-Systeme verwendet. Eine Implementierung, die Verweise zählt, ruft sofort Destruktoren auf, wenn der letzte Verweis gelöscht wird. Für gewöhnliche "Stack"-Objekte bedeutet dies, dass sie sofort aufgeräumt werden, so wie es bei C++ RAII-Objekten geschieht. Der Nachteil ist, dass bei einem Referenzzyklus der Kollektor für die Referenzzählung das Objekt nie entsorgt. Daher haben sie einen sekundären, nicht-deterministischen Garbage Collector, der wie Java- und .NET-Kollektoren funktioniert. Wie .NET mit seinen using-Anweisungen versucht auch cPython, die häufigsten Fälle zu behandeln.

Um also auf die Frage des Autors zu antworten: Nicht-deterministische Garbage Collection vereinfacht die Speicherverwaltung, sie kann auch für andere Ressourcen verwendet werden, solange die Rechtzeitigkeit keine Rolle spielt, und ein anderer Mechanismus (wie sorgfältige Programmierung, referenzzählende GC, eine using-Anweisung oder echte RAII-Objekte) wird benötigt, wenn die rechtzeitige Freigabe anderer Ressourcen erforderlich ist.

1voto

zappan Punkte 3608

Der oben erwähnte Code gibt die erworbenen Ressourcen frei (obwohl ich nicht glaube, dass Sie die Dispose()-Methode selbst aufrufen sollten, denn mit dem Freigeben der Ressourcen ist das Schließen von Streams und dergleichen gemeint). GC entfernt das Objekt aus dem Speicher (gibt den vom Objekt verwendeten Speicher frei), aber das kann nur geschehen, nachdem die Ressourcen vom Objekt freigegeben wurden.

1voto

sblundy Punkte 59298

Ich bin mir bei c# nicht so sicher, wonach das aussieht, aber normalerweise verwaltet der Garbage Collector den Speicher. Diese Verbindung verfügt neben dem Objektspeicher auch über Serverressourcen. Die Datenbank, die sich in einem separaten Prozess befindet, muss eine Verbindung aufrechterhalten. Das Schließen räumt diese auf.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X