Java OutOfMemoryError

Helios co.

Lt. Commander
Registriert
März 2005
Beiträge
1.863
Hi @all,

folgende Situation: Ich babe ein Programm, welches bis zu 10 Threads zur selben Zeit nutzt.
Was es im grunde macht ist simpel: Es holt sich einen Datensatz aus der DB, macht diesen zu einem String, bearbeitet diesen und speichert das Ergebnis wieder in der DB.

In dieser (beschriebenen) Form klappt das Programm perfekt!
Jetzt habe ich allerdings eine weitere Station im "Bearbeiten" Teil eingefügt (es handelt sich hierbei um den BananaSplitter). Der String wird vorher, quasi extra vorbereitet, dann wieder zurückgegeben und ab hier läuft wieder alles wie gehabt.

Aus irgendeeinem Grund, kriege ich jetzt dabei allerdings folgenden Fehler:
Code:
Exception in thread "Thread-5" java.lang.OutOfMemoryError: Java heap space
	at org.apache.xerces.validators.common.XMLValidator.callStartElement(XMLValidator.java:1301)
	at org.apache.xerces.framework.XMLDocumentScanner.scanElement(XMLDocumentScanner.java:1806)
	at org.apache.xerces.framework.XMLDocumentScanner$ContentDispatcher.dispatch(XMLDocumentScanner.java:1182)
	at org.apache.xerces.framework.XMLDocumentScanner.parseSome(XMLDocumentScanner.java:381)
	at org.apache.xerces.framework.XMLParser.parse(XMLParser.java:1098)
	at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:195)
	at java.util.XMLUtils.getLoadingDoc(Unknown Source)
	at java.util.XMLUtils.load(Unknown Source)
	at java.util.Properties.loadFromXML(Unknown Source)
	at de.drni.bananasplit.xmldict.XmlDictionary.<init>(XmlDictionary.java:96)
	at de.drni.bananasplit.xmldict.XmlDictionary.<init>(XmlDictionary.java:67)
	at MyBananaSplitter.myBananaSplitter(MyBananaSplitter.java:29)
	at CollectionProcessor.processText(CollectionProcessor.java:149)
	at CollectionProcessor.process(CollectionProcessor.java:112)
	at CollectionProcessor.run(CollectionProcessor.java:76)
	at java.lang.Thread.run(Unknown Source)

Für sich alleine funktionieren beide Teile (also das Hauptprogramm und auh der BananaSplitter) einwandfrei.
D.h. ich denke, dass ich Endlosschleifen ausschließen kann.
Nicht genug Arbeitsspeicher? Würdemich sehr wundern.
Hat jemand eine Idee woran das liegen könnte?

Thx.
 
Als IDE benutze ich Eclipse.
Wenn ich mich nicht irre, kann man hier in der Eclipse.ini die Xms und Xmx Werte einstellen.
Diese habe ich jetzt wie folgt gesetzt:
Code:
-Xms128m
-Xmx1024m
Das Problem besteht aber weiterhin.

(Der Rechner hat auch nur 1Gb RAM)
Ich kann mir einfach nicht vorstellen, dass das Bischen Splitter das Fass zum Überlaufen bringt.

Hmm, zu tiefe Rekursion?
 
Ja, ich kenne diese Fehlermeldung nur daher, wenn eine Methode sich selber aufruft und es kein Abbruchkriterium gibt oder dieses zu spät greift.
 
Versuch doch mal, was passiert, wenn du deiner Anwendung per -Xms und -Xmx mehr Speicher gibst. Das kannst du in der Eclipse im Menü unter Run->Run configurations... in der Registerkarte Arguments und dann im Textfeld VM arguments einstellen.

Wenn du das in der eclipse.ini einstellst, bezieht sich das nur auf die Eclipse selbst, aber nicht auf Anwendungen, die du aus der Eclipse heraus startest.
 
@Cobinja

Jap, das hat gefunzt.

Ich habe jedoch den Speicheraufwand der java.exe im Taskmanager verfolgt und war geschockt.
Auf einem kleinen Testdatensatz hat das Ding bereits eine Größe von ca 250 mb angenommen.

D.h.wenn ich das Programm auf den richtigen Datensatz loslasse, kann ich getrost davon ausgehen, dass das Problem wieder auftauchen wird.

Ich kann mir nur nicht wirklich vorstellen woran das liegt.
Der BananaSplitter wird für jedne Datensatz neu initialisiert. Dabei liest er eine XML Datei von ca 350kb ein.
Könnte das Speicherproblem hier seine Ursache haben? Und könnte ich es beseitigen, in dem ich das Ding als Singleton implementiere?

Thx
 
Jag einfach mal einen Profiler über dein Programm und guck, wo der Speicher bleibt.
 
Habe ich. Und zwar den YourKit Java Profiler.
Ich werde aus dem Ding leider nicht schlau. Zumindest ist nicht auf Anhieb ersichtlich, in welcher Methode (Klasse wäre auch schon prima) wieviel Speicher draufgeht.
Das einzige dass mir das Ding liefert (sowie ich das sehe) ist der gesamte Bedarf und was alles aufgerufen wurde.
Dafür bräuchte ich aber keinen Profiler :freak:

Falls jemand das Ding kennt (oder eine bessere Alternative), würde ich mich über Belehrungen freuen ;)
 
Das ist mir beim Verarbeiten von (sehr) großen Bildern und langen Strings auch schon passiert. Beim String war das Problem sehr leicht zu lösen, in dem ich diesen einfach ab einer bestimmten Größe in eine Liste geschrieben habe und danach wieder von neuem gefüllt habe.

Bei den Grafiken war das wesentlich schwerer. Dort war die Lösung die Grafik in kleine Byte Arrays zu zerlegen und diese dann Häppchenweise einzulesen. Problematisch wird's wenn man fremde libs benutzt, da man dort in der Regel keinen Einfluss auf die Implementierung hat.

Also falls das Problem in dem von dir geschriebenen Teil des Codes zu suchen sein sollte, dann würde ich einfach mal nach überlangen Variablen schauen, wie z.B. Video/Bild Objekte oder Strings.
 
Zuletzt bearbeitet:
Helios co. schrieb:
Habe ich. Und zwar den YourKit Java Profiler.
Ich werde aus dem Ding leider nicht schlau. Zumindest ist nicht auf Anhieb ersichtlich, in welcher Methode (Klasse wäre auch schon prima) wieviel Speicher draufgeht.
Das einzige dass mir das Ding liefert (sowie ich das sehe) ist der gesamte Bedarf und was alles aufgerufen wurde.
Ich denke dann hast du es falsch bedient. Würde mich sehr wundern, wenn der das nicht kann. Alternativ kannst du auch einfach den von Netbeans nehmen.
 
Zurück
Oben