Frage wegen Heap-Speicher

HPL

Aktives Mitglied
Ich habe mal eine Frage in Bezug auf den Heap-Speicher.

Ich habe einen riesigen Text. Ich bin mit einem BufferedReader wie folgt über diesen drübergegangen.

Java:
BufferedReader br = new BufferedReader(new FileReader("dateiname"));
            String line = br.readLine();

            while(line != null){

line.replaceAll(...)

 line=br.readLine();

Jede einzelne Zeile wollte ich aus bestimmten Gründen manipulieren, indem ich mit replaceAll(String regex, String s) bestimmte Zeichen eliminiere. Ich habe dann aber jedes Mal einen GC out of limits-Error bekommen (also letztlich gab es nicht genug HeapSpeicher für die ganzen auf diese Weise entstandenen regex-Strings, falls ich das richtig verstanden habe.)

Ich habe bereits für dieses Problem eine Lösung gefunden. Aber nun meine Frage:

Wenn ich bei jeder einzelnen Iteration in der while-Schleife (siehe oben) line.substring(0, 10) (anstatt line.replaceAll(...)) schreibe, also einen substring: Bekomme ich dann dasselbe Problem? Landen dann irgendwelche substrings auf dem Heap, so wie dies bei meinen regexen der Fall war? Ich studiere kein Informatik, daher habe ich nie eine AlgoDat-Vorlesung besucht.

Im Voraus vielen Dank für Tips / Antworten.

HPL
 
Diese Frage hätte ich vor kurzem noch mit "Ja" beantwortet. War es nicht irgendwann mal so, dass durch "substring()" das stringinterne Chararray ("value") nicht kopiert, sondern lediglich "offset" und "length" neu gesetzt wurden? Nach einem Blick in die API aber, erschliesst sich einem, dass dem nicht (bzw. nicht mehr?) so ist. Hab' ich was verpasst?
Bei "replaceAll()" bekommst du auf jeden Fall ein String mit neuem Chararray, weil eine dort verwendete Methode einen Stringbuilder instanziert.
 
Zuletzt bearbeitet von einem Moderator:
alleine die denkweise ist falsch ...

warum denn den GANZEN text gleichzeitig im RAM haben wenn es nur darum geht zeile für zeile zu arbeiten ?

in diesem fall sollte man etwas nach folgender idee machen

1) mit readLine() die nächste zeile lesen
2) die aktuelle zeile manipuliren / verarbeiten / damit sonstwas anstellen
3) die modifizierte zeile mit println() eines PrintStreams wieder in eine neue datei rausschreiben
4) eventuelle ergebnisse ebenfalls in eigene datei / datenbank rausschreiben
5) speicher aufräumen
6) 1 bis 5 so lange wiederholen bis input vollständig abgearbeitet wurde

dadurch liegt immer nur die aktuelle zeile im RAM sowie die daten die für deren verarbeitung gebraucht werden ... die beim nächsten schleifen-durchlauf entweder alle durch den GC aufgeräumt oder wiederverwendet werden ...
dadurch sparst du einiges an heap und musst nicht mit vm-args den heap vergrößern ...
 

Neue Themen


Zurück
Oben