[Java] ByteStream erzeugen

Seiten: 1, 2
Huggybear
Verfasst am: 16.04.2012 um: 16:27 Uhr
 
Cw Insider
Wirths Sammler
CwID: 59220
Beiträge: 202
SPAM:
0% Spam

Holla,
ich stehe vor einem Problem in Java. Um eine Klasse von mir zu testen benötige ich einen "unendlichen" Stream.
Der Stream soll wirklich lang sein, sowas in Richtung 100 -Millionen bis einige Milliarden Zeichen.

Meine Methode baut mir auch nen Stream zusammen, nur wirft mir die bei 40 - Millionen Zeichen schon nen OutOfMemoryError.

for(long j = 0; j < numchar2; j++) {
                sb.append(char2)
}

sb ist hier bei mir ein StringBufferobjekt.

Kennt jemand eine Möglichkeit, mit deren Hilfe ich so einen langen Stream zusammenbekomm?


MfG
Huggybear
 



consider
Verfasst am: 16.04.2012 um: 18:48 Uhr
 
Dr. CwCity.de
Community God
CwID: 157538
Beiträge: 4210
SPAM:
0% Spam
Ist das konzeptionell so wirklich gut durchdacht? "Unendlich" geht ja von der Sache her nicht, da ja tatsächlich auch die Daten in den Speicher müßen, wenn du damit arbeiten möchtest. Kannst höchstens mal gucken, wieviel Speicher der JRE zugewiesen ist und diesen erhöhen. Zusätzlich kanns du vor der Aktion mal alles, was du nicht brauchst dereferenzieren und den GC anschubsen um den Speicher aufzuräumen.

-------------

Regeln für gutes Softwaredesign



  1. Wiederverwendung von Code ist besser als Duplizierung.

  2. Daten kapseln.

  3. Immer gegen Schnittstellen, möglichst nicht gegen konkrete Implementierungen programmieren.

  4. Schnittstellen erweiterbar halten.

  5. Keine monolithischen Strukturen.

  6. Vererbung sorgt für starre Strukturen. Objektkompostitionen sind flexibler.

  7. Auf lose Kopplung der Klassen achten. Feste Abhängigkeiten zwischen einzelnen Klassen vermeiden. 


PHP Design Patterns, 2. Auflage von Stefan Schmidt. O'Raily Verlag. ISBN 3-89721-864-2

-----------------

Letzte Änderung am: 16.04.2012 um: 18:51 Uhr durch: consider
 

mbertram
Verfasst am: 16.04.2012 um: 19:29 Uhr
 
Cw Insider
Wirths Sammler
CwID: 155547
Beiträge: 157
SPAM:
0% Spam
Die OutOfMemoryException wird vom StringBuffer erzeugt. Der ist nunmal begrenzt. Wenn Du "unendlich" viele Zeichen zusammensetzen willst, solltest Du besser die String-Klasse nutzen und die einzelnen Zeichen durch den Operator += konkatenieren. Etwa so:


package com.mbe.streamtest;

public class EndlessStreamTest {
    private long numchar = 50000000;
    private char character = 'c';
    private String outputString;

    public static void main(String[] args) {
        new EndlessStreamTest();
    }

    public EndlessStreamTest() {
        for (long j = 0; j < numchar; j++) {
            outputString += character;
        }


        System.out.println(outputString);
    }
}




Letzte Änderung am: 16.04.2012 um: 19:32 Uhr durch: mbertram
 

Huggybear
Verfasst am: 16.04.2012 um: 20:14 Uhr
 
Cw Insider
Wirths Sammler
CwID: 59220
Beiträge: 202
SPAM:
0% Spam

Danke erstmal für eure Antworten. Den Speicher der JVM hatte ich bereits erhöht, das Ergebnis war leider das gleiche.

Sinn macht das ganze nicht so wirklich viel. Nur insofern, dass meine Klasse die den Stream verarbeitet mit sehr großen Streams getestet werden soll, um eventuell auftretende Fehlfunktionen zu ermitteln.

  
outputString += character;
scheint zwar zu funktionieren, ist aber halt leider sehr langsam. Hilft aber nichts, dann läuft das halt erstmal ne zeitlang


MfG
Huggybear
 

mbertram
Verfasst am: 16.04.2012 um: 20:54 Uhr
 
Cw Insider
Wirths Sammler
CwID: 155547
Beiträge: 157
SPAM:
0% Spam
  

scheint zwar zu funktionieren, ist aber halt leider sehr langsam. Hilft aber nichts, dann läuft das halt erstmal ne zeitlang


Stimmt, ich hatte vergessen zu erwähnen, dass String-Konkatenierung sehr inperformant ist. Das sollte man in der professionellen Programmierung auch möglichst vermeiden. Dafür gibt's in der Tat den StringBuffer. Aber der ist nunmal speichermäßig begrenzt. In der Regel reicht der reservierte Speicher des StringBuffer aber aus. Und wenn nicht, dann ist im Quellcode eine Menge faul...


 

Huggybear
Verfasst am: 16.04.2012 um: 22:25 Uhr
 
Cw Insider
Wirths Sammler
CwID: 59220
Beiträge: 202
SPAM:
0% Spam

Ich lege mir mit StringBuilder sb = new StringBuilder(100000000); einen StringBuilder an. Das funktioniert noch. Wenn ich aber höher gehe, ists egal wieviel Speicher ich Java zur verfügung stelle, ich bekomm immer einen OutOfMemoryError.

Sonst ist in der Methode nicht viel Code vorhanden der viel Speicher fressen könnte. An sich nur 2 Schleifen die je dreimal durchlaufen (führen nur append() durch) und eben meine Schleife die den stringbuilder an sich komplett füllen sollte.




MfG
Huggybear
 

mbertram
Verfasst am: 17.04.2012 um: 05:34 Uhr
 
Cw Insider
Wirths Sammler
CwID: 155547
Beiträge: 157
SPAM:
0% Spam
  
Zitat von Huggybear

Ich lege mir mit StringBuilder sb = new StringBuilder(100000000); einen StringBuilder an. Das funktioniert noch. Wenn ich aber höher gehe, ists egal wieviel Speicher ich Java zur verfügung stelle, ich bekomm immer einen OutOfMemoryError.


Die Speichergröße des StringBuffer hängt auch nicht davon ab, wie groß der für die Java Laufzeitumgebung reservierte Speicher ist. Du kannst diesen noch so hoch einstellen, der Speicher, der vom StringBuffer reserviert wird, ändert sich dadurch nicht. Das liegt einfach daran, dass der StringBuffer von sich aus schon eine fest definierte Speicherreservierung beinhaltet.

Das ist etwa vergleichbar mit einem VARCHAR Datenfeld in einer SQL-Datenbank, das Du auf eine maximale Länge von beispielsweise 50 Zeichen festlegst. In diesem Fall kannst Du noch so viel Platten- oder RAM-Speicher haben, es werden nie mehr als 50 Zeichen in das Feld hineinpassen.


 

Huggybear
Verfasst am: 17.04.2012 um: 12:03 Uhr
 
Cw Insider
Wirths Sammler
CwID: 59220
Beiträge: 202
SPAM:
0% Spam
Ich hab schon gemerkt, dass das nicht allzuviel ändert wenn ich mehr Speicher zur Verfügung stelle. Laut Prozess hat Jave nie mehr als ~500MB  verwendet.

Ich bin nur davon ausgegangen, dass der StringBuilder einen int-Wert akzeptiert (was ja an sich auch der Fall ist) und er somit auch einen Wert in der Umgebung von MAX_VALUE verarbeiten kann.


MfG
Huggybear
 

tuts4you
Verfasst am: 17.04.2012 um: 12:18 Uhr
 
Cw Guru
King
CwID: 164600
Beiträge: 649
SPAM:
0% Spam
Irgendwann ist der RAM eben voll. Bzw der dir zur Verfügung stehende Speicher.
Am besten zu speicherst zwischendurch den Stream auf der Platte (einer Datei) ab, da deine Festplattenbegrenzung mit ziemlicher Sicherheit größer ist als dein RAM ;)
Dann dürfte das Funktionieren.

sg

Schau doch mal vorbei bei http://tuts4you.de :)
 

Huggybear
Verfasst am: 17.04.2012 um: 15:41 Uhr
 
Cw Insider
Wirths Sammler
CwID: 59220
Beiträge: 202
SPAM:
0% Spam

Laut Taskmanager habe ich im Moment des Abbruchs noch ca. 1,5GB freien RAM. Das sollte es an sich nicht sein.
Zwischenspeichern kann ich das ganze leider nicht. Der Stream soll zur Laufzeit erzeugt werder und gleich weiterverarbeitet werden.

Ich beschränke meinen Stream jetzt einfach auf 40 Millionen Zeichen, dass reicht dann schon.


MfG
Huggybear
 

 
Seiten: 1, 2

Folgende User sind hier gerade aktiv:
-

ANZEIGE