Laden...

System.OutOfMemoryException bei Datenbankabfrage

Erstellt von zerberos vor 12 Jahren Letzter Beitrag vor 12 Jahren 2.664 Views
Z
zerberos Themenstarter:in
520 Beiträge seit 2007
vor 12 Jahren
System.OutOfMemoryException bei Datenbankabfrage

verwendetes Datenbanksystem: Oracle

Hallo,

ich möchte eine den Inhalt einer Tabelle komplett in eine DataTable laden. Leider wird der reservierte Speicher beim Abfragen der Datenbank sehr groß und er bricht immer mit einer System.OutOfMemoryException ab. Dabei hat er zu dem Zeitpunkt erst ca 80000 Datensätze abgefragt

Die Tabelle hat 470 Spalten und 542000 Datensätze. Diese muss ich jetzt ein eine Datatable laden um damit später weiterarbeiten zu können

Hat einer nen Vorschlag wie ich das hinbekomme. Hier mein aktueller Code zum abrufen:


            dt = new DataTable();
            OracleDataAdapter da = new OracleDataAdapter(commandstring, con);
                      
            try
            {                
                da.Fill(dt);             
                              
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }

Ich nutze den Namespace System.Data.OracleClient

1.552 Beiträge seit 2010
vor 12 Jahren

Hallo zerberos,

wieso lädtst du so viele Daten auf einmal? Welcher User soll sich darin zurechtfinden?
Normalerweise solltest du den SQL-Command dementsprechend anpassen dass Clientseitig so wenig wie möglich danach mit den Daten weiterarbeiten zu müssen.
Was soll denn da eigentlich noch weitergearbeitet werden? Ist dies in SQL nicht möglich?

Gruß
Michael

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

Z
zerberos Themenstarter:in
520 Beiträge seit 2007
vor 12 Jahren

Jo klar wird das im Normalfall eingeschrängt.

Ich komme jetzt mithilfe des DataReaders und dem aufrufen von GC.Collect() alle 5000 Datensätze auf 131000 Datensätze

Was mich wundert ist, das die Anwendung laut TaskManager auf 970MB speicherauslastung kommt. Und dann ne Meldung kommt. Aber eigendlich ist noch Arbeitsspeicher vorhanden und auch die Auslagerungsdatei auf der Festplatte ist noch da. Warum wird der Bereich nicht genutzt?

Gelöschter Account
vor 12 Jahren

Was mich wundert ist, das die Anwendung laut TaskManager auf 970MB speicherauslastung kommt. Und dann ne Meldung kommt. Aber eigendlich ist noch Arbeitsspeicher vorhanden und auch die Auslagerungsdatei auf der Festplatte ist noch da. Warum wird der Bereich nicht genutzt?

Suche mal nach LOH (Large Object Heap). Das ist internes Speichermanagement. Aber das wird dir dennoch nicht weiterhelfen.

Du willst über 200 Millionen Daten in eine DataTable laden und das wirst du nicht schaffen. Wenn, dann benötigst du eine andere Datenstruktur aber selbst dann, wirst du noch recht große Probleme bekommen. Am besten nimmst du eine Datenstruktur, wo die einzelnen Elemente (Rows) nicht so viel Overhead erzeugen, wie bei der DataTable.

Nebenbei bemerkt... 470 Spalten... ist schon ein wenig viel oder nicht? Normalisierung würde sich hier anbieten. Ich wette, da geht einiges.

6.911 Beiträge seit 2009
vor 12 Jahren

Hallo,

der Taskmanager ist sowieso kein geeignetes Mittel um das Festzustellen. Der perfmon.msc kann da schon exakter den managed Speicher für eine Anwendung ausgeben. Ein Profiler wäre das passende Tool.
Bedenke auch dass in .net ein Objekt nicht größer als 2GB werden kann.

Den Rest haben meine Vorposter schon erwähnt.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

Z
zerberos Themenstarter:in
520 Beiträge seit 2007
vor 12 Jahren

Ok. Danke das mit den Spalten ist natürlich zu viel.

Was ich jetzt noch nicht verstanden habe ist, warum er schon bei ca 1GB sagt kein Speicher mehr vorhanden, obwohl er doch eigendlich 2Gb groß werden dürfte

6.911 Beiträge seit 2009
vor 12 Jahren

Hallo zerberos,

schau dir mal diese Ananlogie an: .NET Memory usage - A restaurant analogy. Darin wird darauf eingegegangen.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

Gelöschter Account
vor 12 Jahren

Weil er sich vergrößern möchte, 1 GB belegt ist und vorsichtshalber mehr als 1 GB reservieren möchte. Dann kommt noch ein wenig Fragmentierung des Speichers hinzu und BOOM.

Aber genau das hättest du durch die Suche auch erfahren, wenn du nach dem gesucht hättest, was ich dir weiter oben geschrieben habe. Du bist nicht der erste, der Bekanntschaft mit diesem Effekt gemacht hat.

3.825 Beiträge seit 2006
vor 12 Jahren

Die Tabelle hat 470 Spalten und 542000 Datensätze. Diese muss ich jetzt ein eine Datatable laden um damit später weiterarbeiten zu können

Ich finde es auch eine schlechte Idee alle Datensätze auf einmal in ein DataTable zu laden.

Was musst Du denn mit den Datensätzen machen ? Anzeigen ? Werte berechnen ?
Es gibt da sicher eine bessere Möglichkeit als das DataTable.
Kannst Du einen DataReader verwenden ?

Grüße Bernd

Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3