TreeSet benötigt zu viel Speicher

Status
Nicht offen für weitere Antworten.

soulspirit

Mitglied
Hi,

ich würde gerne auf meiner Postgresdatenbank ein paar Performancetests durchführen.
Deshalb hab ich erstmal ca 300000 Datensätze generiert. Die habe ich dann in ein csv-Format geparst, da Postgres von csv-Files direkt einen Bulkload in eine Tabelle machen kann.
Ein Problem ergibt sich jedoch, wenn ich anstatt der 300000 Datensätze nun 3 Millionen Datensätze generieren will:
Code:
public static void main(String[] args) {



        Random rand = new Random();
        TreeSet<Integer> idxTree = new TreeSet<Integer>();
        TreeSet<String> nickTree = new TreeSet<String>();
        //ArrayList<Integer> idxArray = new ArrayList<Integer>();
        //ArrayList<String>  nickArray = new ArrayList<String>();
        Integer index = null;
        StringBuilder sb = new StringBuilder();
        String newLine = System.getProperty("line.separator");
        String nickname = null;

        try {
            FileOutputStream fout = new FileOutputStream("records.csv");
            PrintStream ps = new PrintStream(fout);

            for (int j = 0; j < 100; j ++){
                for (int i = 0; i < 30000; i++){
                    index = rand.nextInt(1000000);
                    if (!idxTree.contains(index)){
                        .... ein paar StringBuilder.append() 's
                        //index
                        idxTree.add(index);
                        .... ein paar StringBuilder.append() 's
                        while(nickTree.contains(nickname = Main.genWord(rand)));
                        nickTree.add(nickname);
                        .... ein paar StringBuilder.append() 's
                        
                    }
                }
                System.gc();  //versuchsweise GarbageCollector anstupsen
                String temp = sb.toString();  //HIER java.lang.OutOfMemoryError!
                ps.print(temp);
                ps.flush();
                fout.flush();

                System.out.println(new Integer((j+1)).toString() + "Percent...");
                System.out.println("current length of StringBuilder: " + sb.length());
                sb = new StringBuilder();
                
            }
            fout.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
    }
Der Fehler tritt deshalb auf, weil die Treesets einfach zu viele Knoten haben. Bei ca 400000 Knoten wirds der VM zu viel. Gibts ne elegantere Methode sowas zu handeln? Kann ja schlecht 10 mal so viel HeapSpace reservieren (falls das überhaupt geht), außerdem ist das Ganze sogar mit TreeSets ab ca 14% nicht mehr wirklich performant, was vielleicht auch an meienm Rechner liegen mag. Ich brauch die Treesets(oder was vergleichbares) jedoch, da ich sonst Doppelte PrimaryKeys habe.

//edit:
auch ohne den treesets wirds der VM anscheinend zu viel. Der Fehler tritt aber immer noch an der selben Stelle auf:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.lang.String.<init>(String.java:208)
at java.lang.StringBuilder.toString(StringBuilder.java:431)
at Main.main(Main.java:127)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)
 

Wildcard

Top Contributor
Überleg dir doch bitte mal was du hier tust:
Code:
            for (int j = 0; j < 100; j ++){
                for (int i = 0; i < 30000; i++){
                    index = rand.nextInt(1000000);
                    if (!idxTree.contains(index)){
                        .... ein paar StringBuilder.append() 's
Hast du die leiseste Ahnung wie viele Arrays da allokiert und kopiert müssen und wie groß das letzte Array bei ein paar Millionen Einträgen später sein wird?
 

soulspirit

Mitglied
darum mach ich am ende der inneren for-schleife ja ein sb = new StringBuilder(), damit die Datenmenge nicht explodiert.. Aber anscheinend funktioniert das nicht so wie ich das will..

und 30000 schafft die VM locker. Nur wird der Speicher anscheinend nicht mehr freigegeben.
 

Wildcard

Top Contributor
soulspirit hat gesagt.:
und 30000 schafft die VM locker. Nur wird der Speicher anscheinend nicht mehr freigegeben.
Das ist aber auch von der Größe der Strings abhängig.
Weiterhin solltest du unbedingt den StringBuilder auf einen sinnvollen Wert initialisieren um die Anzahl der ArrayCopy Operationen zu minimieren. Für was brauchst du den StringBuilder überhaupt? Du willst doch nur was in den Stream schreiben.
 

Marco13

Top Contributor
Du kannst den Speicher, der für die JVM zur Verfügung steht, angeben, z.B. 1000 MB:
java -Xmx1000m MeinProg

Trotzdem hat Wildcard recht: Wenn du die Daten nur in einen Stream schiebst, besteht eigentlich kein Grund, sie in einem gigantischen(!) String zwischenzuspeichern.
 

soulspirit

Mitglied
Der Grund für den String war, dass ich anfangs dachte es würde vielleicht performancemäßig was rausschauen, wenn ich alles mit einem schnellem StringBuilder zusammenflicke und dann in einem einzigen Schreibvorgang eine große Datenmenge schreibe. Hat sich aber als ein großer Trugschluss erwiesen :?

Inzwischen habe ich ein befriedigendes Ergebnis erhalten:
- Direktes schreiben in den Stream
- In die Treesets immer nur Teile der Indexe gespeichert, indem ich z.b. für usernamen immer 120000 Datensätze mit gleichem Präfix speichere und anschließend das Treeset leere und das Präfix ändere.

So schaffe ich in ca 5 Minuten alle 3Mio Datensätze. Vielleicht wäre noch etwas rauszuholen, für meine Zwecke genügt das jedoch.

Vielen Dank für die hilfreichen Tips :toll:
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
X Collections Fragen zu gleichen Elementen in TreeSet Allgemeine Java-Themen 35
T Collections TreeSet.contains ruft nicht .equals? Allgemeine Java-Themen 4
B TreeSet-Ausgeben Allgemeine Java-Themen 8
B Collections TreeSet/TreeMap, doppelte Einträge zulassen ? Allgemeine Java-Themen 11
K Collections TreeSet beinhaltet Objektleichen Allgemeine Java-Themen 26
S TreeSet - Comparator ändern -> resort? Allgemeine Java-Themen 8
M Vergleich von TreeSet<HashSet>^2 Allgemeine Java-Themen 8
H Problem beim Sortieren einer HashMap mit TreeSet Allgemeine Java-Themen 4
A Effizienzfrage bei TreeSet / XML-Verarbeitung Allgemeine Java-Themen 8
C TreeSet mit Objekten befüllen Allgemeine Java-Themen 12
J TreeSet und Comparator will nicht so wie ich Allgemeine Java-Themen 2
J unsortiertes Treeset Allgemeine Java-Themen 2
J TreeSet neues TreeSet aufbauen Allgemeine Java-Themen 8
S Verhalten der Klasse TreeSet... Allgemeine Java-Themen 4
André Uhres BigDecimal in HashSet eingefügt, aber nicht in TreeSet Allgemeine Java-Themen 2
M TreeSet exception bei add Allgemeine Java-Themen 17
E Statt HashSet die TreeSet verwenden Allgemeine Java-Themen 4
G TreeSet ändert sich bei Änderungen nicht! Allgemeine Java-Themen 15
M Fehler in TreeSet.remove() Allgemeine Java-Themen 6
B String Array aus TreeSet Allgemeine Java-Themen 6
T TreeSet neu sortieren Allgemeine Java-Themen 4
N Hilfe bei RegEx benötigt Allgemeine Java-Themen 3
stroggi Serielle Schnittstelle (jssc) - Flush benötigt? Allgemeine Java-Themen 2
I Methoden Schnelle Hilfe benötigt - Kleines Video/Slideshow aus mehreren Bildern erstellen Allgemeine Java-Themen 3
A Methoden Generische Methode mit Arrays - Source Compatibility 1.7 benötigt, wieso? Allgemeine Java-Themen 3
M Befehl in Runtime ausführen der Eingabe benötigt Allgemeine Java-Themen 3
V Für was benötigt man Apache Common Allgemeine Java-Themen 3
T Interger in String konvertieren Erklärung benötigt Allgemeine Java-Themen 11
D Hilfe bei ZIP-import benötigt Allgemeine Java-Themen 13
D kleine SQL-Hilfe benötigt: not a single-group group function Allgemeine Java-Themen 4
S Welche jar's werden wirklich benötigt?` Allgemeine Java-Themen 5
S Warum benötigt jede Internetseite unbedingt das neuste Java? Allgemeine Java-Themen 11
N Was benötigt man fürs Java Media Framework? Allgemeine Java-Themen 12
T Queue-Hilfe benötigt Allgemeine Java-Themen 4
K ServerSocket benötigt unmengen an Zeit Allgemeine Java-Themen 7
L Objekt in einem Frame wird im anderen benötigt Allgemeine Java-Themen 5
S Dringend Hilfe benötigt Allgemeine Java-Themen 12
M Algorhitmus benötigt Allgemeine Java-Themen 8
J Bei einer Zufallsausgabe werden zu viel Ergebnisse ausgegeben Allgemeine Java-Themen 16
L Java Slick2D stürzt ab- Zu viel auf einmal? (LinkedList) Allgemeine Java-Themen 7
S Java-Programm verbraucht zu viel RAM Allgemeine Java-Themen 8
F Array viel zu groß...andere Lösungen? Allgemeine Java-Themen 12
K htmlCode einlesen, Speicherüberlauf? zu viel code? Allgemeine Java-Themen 21
G Werte bei Rekursion viel höher als erwartet Allgemeine Java-Themen 3
L wan loggt man zu viel Allgemeine Java-Themen 8
N Wie viel Java kann man lernen ? Allgemeine Java-Themen 106
T String.split() - viel zu langsam Allgemeine Java-Themen 9
L Nutzt Java bei Start der VM übermäßig viel Speicher? Allgemeine Java-Themen 3
J Viel Text mit " im Quellcode abspeichern Allgemeine Java-Themen 7
G Panel mit vielen Komponenten verbraucht viel Speicher Allgemeine Java-Themen 3
H wie viel speicher braucht eigentlich ein array? Allgemeine Java-Themen 2

Ähnliche Java Themen

Neue Themen


Oben