DataTable.NewRow() verursacht Speicherleck
-
Hallo,
das Problem ist:
folgender Code belegt 500 MB in 10 Stunden:private void timer_Tick(object sender, EventArgs e) // Intervall 50 ms { DataRow myZeile = myTable["Test"].NewRow(); // Die Tabelle wurde vorher einmalig erstellt. myZeile["Mitarbeiter"] = "Max"; myZeile["Datum"] = DateTime.Now; myZeile = null; }
Weiss jemand wo der Speicherleck sein könnte?
Danke im Voraus
-
Wenn du alle 50 ms eine neue Zeile erstellst, ist klar, dass der Speicher irgendwann voll ist. Das hat meines erachtens nach nichts mit einem Memoryleak zu tun.
-
Na ja, die neue Zeile "DataRow myZeile" wird nicht zur Tabelle "myTable" hinzugefügt.
NewRow() erstellt lediglich eine neue DataRow mit dem Schema der Tabelle
Der von ihr belegter Speicherplatz sollte nach dem Verlassen der Funktion freigegeben werden.
-
Die MSDN sagt zu DataTable.NewRow() folgendes:
Sie müssen die NewRow-Methode verwenden, um neue DataRow-Objekte mit demselben Schema wie DataTable zu erstellen. Nach dem Erstellen einer DataRow können Sie diese über die Rows-Eigenschaft des DataTable-Objekts der DataRowCollection hinzufügen. Wenn Sie neue Zeilen mithilfe von NewRow erstellen, müssen die Zeilen zur Datentabelle hinzugefügt oder daraus entfernt werden, bevor Sie Clear aufrufen.
Daraus schließe ich, das du nur halb recht hast.Besonders aus dem Satz "Wenn Sie neue Zeilen mithilfe von NewRow erstellen, müssen die Zeilen zur Datentabelle hinzugefügt oder daraus entfernt werden, bevor Sie Clear aufrufen." würde ich behaupten, das die Zeile erhalten bleibt.
-
Hab da was gefunden, was dir unter Umständen hilft. Freeing Memory used by old DataRows
Auszug:
Here's an interesting finding about when the memory of a datarow is freed.
if you do this:
DataRow newRow = dataTable.NewRow();
The new row will never be GC'd, even after newRow goes out of scope, and
even though the new row has state "Detached".On the other hand, do this:
DataRow newRow = dataTable.NewRow();
newRow.Table.Rows.Add(newRow);
newRow.Delete(); // changes state to "detached"This allows newRow to be GC'd. This looks like a gimmick to me - it should
not be necessary. But, it works.
-
Vielen Dank. Das werde ich gleich ausprobieren.
-
Hallo,
ich hab es ausprobiert und es scheint geholfen zu haben:
private void timer_Tick(object sender, EventArgs e) // Intervall 50 ms { DataRow myZeile = myTable["Test"].NewRow(); // Die Tabelle wurde vorher einmalig erstellt. myZeile["Mitarbeiter"] = "Max"; myZeile["Datum"] = DateTime.Now; myZeile.Table.Rows.Add(myZeile); myZeile.Delete(); }
Danke
-
Wer weis, was sich MS da wieder gedacht haben.
Hatte vor kurzem ebenfalls ein MemoryLeak Problem, das ich nach c.a. einem halben Tag auf den XmlSerializer als Ursache festlegen konnte.
-
inflames2k schrieb:
Wer weis, was sich MS da wieder gedacht haben.
Hatte vor kurzem ebenfalls ein MemoryLeak Problem, das ich nach c.a. einem halben Tag auf den XmlSerializer als Ursache festlegen konnte.
Da ich auch mit dem XmlSerializer arbeite: Verrätst Du uns mehr zu dem Leak?
Ich bin vor einiger Zeit auf ein MemoryLeak im ReportViewer gestoßen. Der Speicher für Bilder, egal welcher Quelle, wurde von Viewer nicht wieder freigegeben. Also unabhängig von Bitmap-Objekten und einem Dispose auf ihnen, rohen byte-Arrays/blobs aus einer Datenbank oder auch nur URIs zu denen der Viewer eigenständig Bilder lädt. Ich halte es jedenfalls für ein MemoryLeak, da ich auch nach mehrstündiger Suche keine Möglichkeit gefunden habe, den Speicher wieder freizugeben. Workaround: Die Form mit dem Viewer in eine separate Anwendung auslagern und als eigenen Prozess starten. Ansonsten ist mir die Hauptanwendung nach einiger Zeit immer abgeraucht.
-
Bezüglich der MemoryLeak-Quelle beim Xml-Serializer:
Auszug:
To increase performance, the XML serialization infrastructure dynamically generates assemblies to serialize and deserialize specified types. The infrastructure finds and reuses those assemblies. This behavior occurs only when using the following constructors:
System.Xml.Serialization.XmlSerializer(Type)
System.Xml.Serialization.XmlSerializer(Type,String)
If you use any of the other constructors, multiple versions of the same assembly are generated and never unloaded, resulting in a memory leak and poor performance. The simplest solution is to use one of the two constructors above. Otherwise, you must cache the assemblies in a Hashtable, as shown in the following example.
Anhand des MSDN Beitrags sollte klar werden, worin die Leak-Quelle besteht. - Eine Möglichkeit das zu umgehen steht ja im Text.