# OutOfMemoryError - Wie verhindern?



## jf (30. Aug 2010)

Hallo, ich möchte Daten aus mehreren Dateien (7,6GB; 4,5GB; 1,6GB und 1,1GB) einlesen und anschließend weiterverarbeiten. Dies funktioniert bei einer kleinen Testdatenbank bereits wunderbar. Wenn ich mein Programm allerdings auf die kompletten Dateien anwende, erhalte ich nach etwa einer Minute stets den Fehler _java.lang.OutOfMemoryError: Java heap space_

Ich habe bereits versucht über die Xms- und Xmx-Parameter eine Lösung herbeizuführen. Leider ohne jeglichen Erfolg. RAM wäre eigentlich genug verfügbar - nämlich 8GiB (virtueller Speicher käme ja noch oben drauf).

Wie bekomme ich Java dazu, mit solch großen Datenmengen umzugehen?
Oder gibt es evtl. Techniken, welche den Speicherhunger reduzieren?


----------



## Landei (30. Aug 2010)

Die Frage ist, wieviel Daten du *gleichzeitig* verarbeiten musst. Musst du wirklich alles im Speicher halten, kannst du Komprimierungstechniken versuchen (z.B. kann ein Set von Strings in einem Trie gespeichert werden), Caching u.s.w., aber das hängt stark vom Typ der Aufgabe ab. Ansonsten halt tausend Sätze holen, verarbeiten, die nächsten tausend u.s.w. 

Oft lassen sich bestimmte Teile der Aufgabe auch schon mit SQL / PL/SQL / TSQL erledigen, das hilft manchmal enorm.


----------



## jf (30. Aug 2010)

Landei hat gesagt.:


> Die Frage ist, wieviel Daten du *gleichzeitig* verarbeiten musst. Musst du wirklich alles im Speicher halten, kannst du Komprimierungstechniken versuchen (z.B. kann ein Set von Strings in einem Trie gespeichert werden), Caching u.s.w., aber das hängt stark vom Typ der Aufgabe ab. Ansonsten halt tausend Sätze holen, verarbeiten, die nächsten tausend u.s.w.
> 
> Oft lassen sich bestimmte Teile der Aufgabe auch schon mit SQL / PL/SQL / TSQL erledigen, das hilft manchmal enorm.


Ich muss verschiedene Datensätze (welche quer über die Datenbank verstreut sind) zu einer Datei zusammenfassen. Die interessierenden Werte der jeweiligen Datensätze werden in einem Objekt abgelegt. Viele dieser Objekte befinden sich auf einem Vektor - die Datei wird dann auf einmal geschrieben. Wenn ich es -wie du sagst- stückweise erledigen will, müsste ich einige Quelltextteile noch einmal umschreiben... übersichtlicher wird es dabei sicherlich auch nicht.
Von daher wäre mir eine Möglichkeit lieber, bei welcher ich alles auf einmal einlesen kann.
Mit Datenbanken habe ich leider noch nicht gearbeitet. Wie schnell komme ich da rein? Was würdest du mir empfehlen (ich kenne die Unterschiede zwischen SQL, PL/SQL und TSQL leider nicht)
Ich habe nun auch die 64bit JRE und 64bit Eclipse installiert - nun sollte es bezüglich des Speichers doch keine Probleme mehr geben, oder?

Wie funktioniert überhaupt ein BufferedReader? - Bleiben dabei alle Zeilen, welche gelesen wurden, im Speicher? (dies wäre nämlich z. B. nicht nötig)


----------



## tuttle64 (30. Aug 2010)

jf hat gesagt.:


> Von daher wäre mir eine Möglichkeit lieber, bei welcher ich alles auf einmal einlesen kann.




kann ich verstehen, aber manchmal geht das eben aufgrund der grossen datenmenge oder anderen gründen nicht. das betrifft nicht nur den speicher auf deiner maschine sondern auch die unnötige netzlast, die du so verursachst. wie Landei bereits gesagt hat, macht es sinn, die vorselektion der daten als sql-statement gegen die db abzusetzen und dann nur noch mir den viel geringeren datenmengen des resultsets zu arbeiten. mit sql kannst du verschiedene datensätze über die ganze db zusammenführen, filtern und dann das resultat von deinem java programm abholen lassen.




jf hat gesagt.:


> Die interessierenden Werte der jeweiligen Datensätze werden in einem Objekt abgelegt.




von wievielen objekten sprichst du hier?


----------



## SlaterB (30. Aug 2010)

@jf
in jedem Fall gibt es allgemein in direkter Programmierung keine Möglichkeit, beliebig viele Daten gleichzeitig zu bearbeiten,
jedes andere Programm arbeitet auch 'stückchenweise', das musst du dir angewöhnen, dazu gibts fast keine Alternative,

eine aber doch, das Programm nicht für sich loslassen sondern in eine virtuelle Umgebung einbetten in der beliebig viel Speicher vorgegaukelt wird, der dann von der Umgebung wie jeweils benötigt stückchenweise von der Festplatte geladen und passend zur Verfügung gestellt werden,
in so einem Kontext könnte dein Originalcode laufen, mit dem kleinen Nachteil dass dafür dann wahrscheinlich MB an Code und Monate bis Jahre zu programmieren wäre 
falls es das nicht schon fertig gibt, virtuellen Speicher kannte schon MSDOS


----------

