Autor |
Beitrag |
erther
Hält's aus hier
Beiträge: 8
|
Verfasst: Do 25.03.10 12:46
Hallo,
ich habe folgendes Problem. Ich verwende List<T> mit T=string und lese in einer Schleife eine Datei Zeilenweise aus, die ich in die Liste speichere. Die Datei (bzw. Dateien) sind teilweise echt lang und ich bekomme System out of Memory.
Was kann ich tun? Besteht bei List<T> eine Beschränkung?
Vielen Dank für die Hilfe!
erther
|
|
bakachan
      
Beiträge: 503
Erhaltene Danke: 34
W7 (x64) Ultimate
C# / VB.NET (VS2010 Ultimate)
|
Verfasst: Do 25.03.10 13:12
List<T> hat soweit ich weiss keine Beschränkung was die Größe angeht also wird wohl der RAM deines Systems voll sein (wie die Fehlermeldung ja auch besagt).
|
|
erther 
Hält's aus hier
Beiträge: 8
|
Verfasst: Do 25.03.10 13:36
Wenn ich die Elemente aus der Liste haue sobald ich sie nicht emhr brauche und dann erst neue Elemente einfüge, sollte das Problem behoben sein?!
|
|
danielf
      
Beiträge: 1012
Erhaltene Danke: 24
Windows XP
C#, Visual Studio
|
Verfasst: Do 25.03.10 14:44
Hallo,
ich denke nicht, dass bei einer normale Verwendung von List<T>es zu einem System out of Memory kommt. Für sowas gibt es paging/swapping etc.
Was bedeutet das die Datei teilwese echt lang sind? Für meine Diskette sind 500kb ne Menge Holz
Und zeig mal bitte Code vom einlesen, ich vermute du hast da einen Programmierfehler.
Gruß
|
|
erther 
Hält's aus hier
Beiträge: 8
|
Verfasst: Do 25.03.10 16:41
Ok, hier ein Codeschnippsel, wie ich meine Liste befülle. Mit groß meine ich so ca. 500 MB.
C#-Quelltext 1: 2: 3: 4: 5: 6: 7:
| List<string> testarr = new List<string>(); StreamReader sr_extrakt = new StreamReader(path); while (sr_extrakt.Peek() >= 0) { string line_out = sr_extrakt.ReadLine(); testarr.Add(line_out); } |
Als Beispiel: Hab ca. 5,5 Mio Elemente in der Liste drin und das Programm belegt ca. 1.1 GB RAM.
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: Do 25.03.10 16:48
Selbst wenn das keine Unicode-Datei ist, dürfte der Speicherverbrauch nicht viel höher als 1 GB liegen  (/edit:  ). Von wie viel Arbeitsspeicher sprechen wir denn?
Aber da an dem Code nichts auszusetzen ist:
erther hat folgendes geschrieben : | Wenn ich die Elemente aus der Liste haue sobald ich sie nicht emhr brauche und dann erst neue Elemente einfüge, sollte das Problem behoben sein?! |
Ja. Wenn auf die String-Instanzen keine Referenz mehr besteht, können sie vom GC abgeräumt werden. Und das tut er spätestens vor einer OOM-Exception.
_________________ >λ=
|
|
erther 
Hält's aus hier
Beiträge: 8
|
Verfasst: Do 25.03.10 17:42
Danke für die Diskussion!
Ich lese jetzt 500 Elemente als Block in meine Liste und entferne die nicht gebrauchten Elemente dann. Anschließend lese ich die nächsten 500 usw...
Hab mit C# (respektive der Programmierung im allgemeinen) noch nicht viel gemacht und stoße daher immer mal wieder auf teilweise Grundlagenfragen. Aber hier wird einem ja immer gut geholfen 
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: Do 25.03.10 17:59
Wenn du sowieso jede Zeile einzeln behandelst, könntest du dir auch einmal IEnumerable<T> anschauen. Damit kannst du "Lazy Sequences" ermöglichen, bei denen idealerweise immer nur ein Element gleichzeitig im Speicher liegt.
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| static IEnumerable<string> ReadLines(string path) { using (StreamReader reader = new StreamReader(path)) while (true) { string line = reader.ReadLine(); if (line == null) yield break; yield return line; } }
ReadLines(path).Sum(line => line.Length); |
_________________ >λ=
Zuletzt bearbeitet von Kha am Do 01.04.10 21:13, insgesamt 1-mal bearbeitet
|
|
traceurmicha
      
Beiträge: 160
Erhaltene Danke: 9
Win XP SP2, Win 7 Pro., Ubuntu 9, Debian 5
C#, ASP.NET, MSSQL, PHP(Microsoft Visual Studio 2010 Ultimate, SharpDevelop 4, Microsoft SQL Server2008 Express, Eclipse for PHP)
|
Verfasst: Do 01.04.10 13:23
_________________ Programmieren ist ein Rennen zwischen den Softwareentwicklern, die versuchen größere und bessere idiotensichere Programme zu schreiben und dem Universum, welches versucht größere und bessere Idioten zu produzieren. Zur Zeit liegt das Universum in Führung.
|
|
danielf
      
Beiträge: 1012
Erhaltene Danke: 24
Windows XP
C#, Visual Studio
|
Verfasst: Do 01.04.10 13:39
Jepp, bekommst du
Eine Variable erstellt er sowieso nicht  Höchstens legt er ein neues string-Objekt an.
Früher war es durchaus "wichtig" die Variable außerhalb einer Schleife zu deklarieren. Weil zur Laufzeit, wie du sagst, dann in jedem Durchlauf neuer Speicher für das Objekt allokiert wird. Mittlerweile ist es so, dass die Kompiler dies erkennen und bei der Übersetzung die Deklaration so oder so außerhalb machen.
Gruß
|
|
traceurmicha
      
Beiträge: 160
Erhaltene Danke: 9
Win XP SP2, Win 7 Pro., Ubuntu 9, Debian 5
C#, ASP.NET, MSSQL, PHP(Microsoft Visual Studio 2010 Ultimate, SharpDevelop 4, Microsoft SQL Server2008 Express, Eclipse for PHP)
|
Verfasst: Do 01.04.10 13:59
alles klar danielf, dan rewidiere ich meine Aussage hiermit
man lernt ebend nie aus 
_________________ Programmieren ist ein Rennen zwischen den Softwareentwicklern, die versuchen größere und bessere idiotensichere Programme zu schreiben und dem Universum, welches versucht größere und bessere Idioten zu produzieren. Zur Zeit liegt das Universum in Führung.
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: Do 01.04.10 21:06
traceurmicha hat folgendes geschrieben : | wäre es nicht besser man würde schreiben |
Wenn es lesbarer ist, ist es besser. Ist es das  ?
danielf hat folgendes geschrieben : | Früher war es durchaus "wichtig" die Variable außerhalb einer Schleife zu deklarieren. Weil zur Laufzeit, wie du sagst, dann in jedem Durchlauf neuer Speicher für das Objekt allokiert wird. |
Was hat die Deklaration mit Objekt-Allokationen zu tun? Davon gibt es doch wohl in beiden Fällen genauso viele wie Schleifendurchgänge. Die Variable selbst benötigt natürlich Stackspeicher, aber der wird ja nicht allokiert.
Du hast wahrscheinlich eher daran gedacht  .
Mal ganz abgesehen davon, dass wir uns hier in einem Iterator befinden, in dem Variablen sowieso keine Variablen bleiben  ...
_________________ >λ=
|
|