String nicht im String literal pool speichern - Parser

vimar

Bekanntes Mitglied
Hallo,

aus performancegründen (ca 18 Mio String Objekte zur laufzeit) will ich verhindern dass so gut wie alle Strings im String literal pool sind damit System.gc() den kram auch mal löscht und nicht meinen ram zumüllt mit strings die ich nicht mehr brauche (so gut wie alle). ich muss sehr viele textfiles parsen und kriege dadurch viele stringobjekte, aber ansich sind es nur zahlen die ich in einer arraylist speichere.

ich weiss auch dass es ansich sinnvoll ist den String literal pool zu nutzen(wegen den referenzen ansich weniger speicher bei stringobjekten mit selbem content) aber scheinbar läuft das nicht so wie ich will.

kann ich explizit sagen dass ich einen String NICHT in dem pool haben will?

ich erzeuge pro textfile immer eine parserinstanz, die line für line die zahlen ausliest und in einer globalen arraylist<integer> speichert. (derzeit mit strToKenizer, schreibe gerade auf scanner kram um)

FRAGE:
jemand eine konkrete idee (vllt codeschnipsel/pseudocode) wie ich eine textfile auslese, die werte NICHT als string zwischenspeichern muss und die auch intern nicht in den string literal pool kommen weil ich brauch die werte einfach nur in einer arraylist<integer> und garnicht als string.


vielen dank für jegliche hilfe im vorraus!
 

vimar

Bekanntes Mitglied
Danke ich hab mir das eben durchgelesen.

Java:
for (String[] line; (line = in.readLine().split("\\s")) != null;){

meiner meinung nach erzeugt der kopf dieser vorschleife doch durchaus enorm viele strings in diesem Stringarray. werden die wohl nun auch alle im stringpool gespeichert oder? selbst wenn ich dann die instanz = null setzte in der diese forschleife ist, so ist ja dennoch eine referenz vorhanden auf den heap von dem string pool.

und wenn ich
Java:
for (String line; line = in.readLine() != null;){
mache dann müsste doch wegen "String line" auch jede einzelne zeile der textfile im stringpool landen. und wenn ich dann noch anschliessend den string splitte, dann hätte ich doch alle substrings auch noch im pool und insgesamt werden die doch einfach nicht gelöscht.



ich meine ich müsste doch dann logischerweise irgendwie sowas schreiben:

Java:
while (in.readLine() != null){

// genau diese aktuelle zeile die ich jetzt nicht als string zwischenspeicher irgendwie splitten und in //meine arraylist<integer> packen
}

ich begreife gerade dann nicht wie ich in.readLine() in der while benutze wenn ich keinen String auf die line verweise? soll ich zunächst die zeilen zählen? also ne while schleife while != null zeileCount++ und dann wieder an den anfang der datei springen und mit ner forschleife (x=0; x < zeileCount; x++) dann dort einfach in.readLine().split usw?

plz help -.-
 

vimar

Bekanntes Mitglied
Wird nicht hier jede "line" in den pool getan? (zeile 7) :

Java:
for (int m =0; m < 3; m++){

         vcount = 0;
         while (vcount < 7){
          vcount++;

          line = in.readLine().split("\\D");
           for (int x=1; x<line.length; x++){ // 0 = ""
                 kPoint.getList().add(Integer.valueOf(line[x]));
            }
  
                          }
                            AAO_kPointList.add(kPoint.getList());
                            
  
}
 

Volvagia

Top Contributor
Nein. readLine benutzt einen StringBuffer:

Java:
public synchronized String toString() {
	return new String(value, 0, count);
}

String.split benutzt einen Pattern der wiederrum subSequence benutzt:

Java:
public String substring(int beginIndex, int endIndex) {
	if (beginIndex < 0) {
		throw new StringIndexOutOfBoundsException(beginIndex);
	}
	if (endIndex > count) {
		throw new StringIndexOutOfBoundsException(endIndex);
	}
	if (beginIndex > endIndex) {
		throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
	}
	return ((beginIndex == 0) && (endIndex == count)) ? this :
	    new String(offset + beginIndex, endIndex - beginIndex, value);
    }
 
S

SlaterB

Gast
Code wie deinen verwendet jeder und nichts davon landet im Pool normalerweise,
Speicherprobleme erhälst du vielleicht, wenn du selber die Strings irgendwo merkst

im folgenden Testprogramm gibt es bei mir mit Standard-Speicher einen OutOfMemoryError bei cache nach 700.000,
der hier unsauber abgefangen wird, ohne cache läuft es es bis 2 Mio. durch

Java:
public class Test {
    public static void main(final String[] args) {
        try   {
            test(true);
        }    catch (Throwable t)  {
            System.out.println(t.toString());
        }
        test(false);
    }

    static void test(boolean cache)  {
        List l = new ArrayList();
        for (int i = 0; i < 2000000; i++)    {
            String st = "hallo String " + i;
            if (cache)   {
                l.add(st);
            }
            if (i % 100000 == 0)  {
                System.out.println("i: " + i);
            }
        }
    }
}
 

vimar

Bekanntes Mitglied
Also falls jemand den "fehler" sieht, genau diese klasse haut mir den heap voll mit 18 Mio String Objekten. Sieht irgendjemand den fehler?

von dieser klasse werden aktuell ca 350 instanzen erstellt.

Java:
import SIFT.siftKeyPoint;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import SIFT.siftKeyPoint;
import java.io.*;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author vimar
 */
public class csiftparser {

    String filename;
    int vcount;
    String firstline;
    String temp;
    FileReader fr;
    LineNumberReader in;
    ArrayList<ArrayList<Integer>> AAO_kPointList;
    siftKeyPoint kPoint;
    double akt_X;
    double akt_Y;
    double akt_Scale;
    double akt_Orientation;

    public csiftparser(String filename) throws InterruptedException {

        this.filename = filename;

        AAO_kPointList = new ArrayList<ArrayList<Integer>>();

        try {
            in = new LineNumberReader(fr = new FileReader(filename));

            vcount = 0;

            in.readLine(); // skip first line cause noneed

            for (String[] line; (line = in.readLine().split("\\s")) != null;) {

                akt_X = Double.parseDouble(line[0]);
                akt_Y = Double.parseDouble(line[1]);
                akt_Scale = Double.parseDouble(line[2]);
                akt_Orientation = Double.parseDouble(line[3]);

                for (int m = 0; m < 3; m++) {
                    kPoint = new siftKeyPoint();
                    kPoint.setX(akt_X);
                    kPoint.setY(akt_Y);
                    kPoint.setScale(akt_Scale);
                    kPoint.setOrientation(akt_Orientation);

                    vcount = 0;
                    while (vcount < 7) {
                        vcount++;
                        line = in.readLine().split("\\D"); // vllt die ursache string pool?

                        for (int x = 1; x < line.length; x++) { // 0 = ""
                            kPoint.getList().add(Integer.valueOf(line[x]));

                        }

                    }
                    AAO_kPointList.add(kPoint.getList());

                }

            }

        } catch (NullPointerException e) {
            System.out.println("Fertig mit Datei");
            System.out.println(filename + "Fertig bearbeitet!");
        } catch (IOException ex) {
            Logger.getLogger(csiftparser.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            if (fr != null) {
                try {
                    System.out.println("allet weg");
                    fr.close();
                    in.close();

                    //System.gc();

                } catch (IOException e) {
                }
            }
        }

    }

    public synchronized ArrayList<ArrayList<Integer>> getKeyPointList() {

        //return KeyPointList;
        return AAO_kPointList;
    }
}

als input habe ich solche files:

372 128 3
277.65 513.45 55.57 1.032
42 141 67 3 0 0 0 0 62 47 13 14 26 54 12 12 0 0 2 8
98 104 7 0 0 1 4 5 15 7 0 0 134 101 19 0 0 0 10 55
141 73 4 1 7 54 57 87 11 6 7 13 141 141 61 19 0 2 21 23
95 31 0 0 57 11 3 0 0 0 5 18 141 141 80 3 4 6 5 28
9 54 49 13 117 65 5 4 0 0 2 5 35 8 0 0 0 2 2 0
0 0 0 0 1 22 16 0 0 0 0 0 0 3 1 0 0 0 0 0
0 0 0 0 0 0 0 0
31 49 22 121 94 17 4 16 8 7 21 81 51 22 15 7 169 83 4 6
4 15 13 15 47 26 0 0 0 0 0 0 4 0 0 66 154 53 10 14
74 1 0 19 67 37 48 130 101 37 0 0 0 89 131 57 82 44 0 0
0 0 12 15 3 0 1 42 15 0 12 57 57 0 0 10 7 5 56 227
14 0 0 0 0 28 66 29 7 0 0 0 0 0 10 6 0 0 0 0
0 0 5 8 0 0 0 0 0 0 23 20 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
113 29 7 20 33 29 8 80 59 34 15 5 6 6 10 66 5 20 10 12
160 83 2 4 0 0 0 0 49 25 0 0 170 83 20 16 2 0 0 72
82 51 45 120 44 1 0 19 0 95 114 49 100 32 0 0 0 1 9 11
87 43 0 0 19 0 22 56 0 0 0 48 11 13 110 223 12 0 0 12
0 34 68 26 4 0 0 0 0 1 7 5 8 0 0 0 0 0 6 8
0 0 0 0 0 3 30 17 0 0 0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0
448.92 204.94 25.59 2.843
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
7 1 0 0 22 0 0 0 4 2 2 34 9 0 0 0 38 68 2 2
126 35 0 0 6 20 4 11 59 11 0 1 71 29 12 18 71 5 3 0
20 14 23 126 9 5 24 16 98 126 47 14 126 11 0 0 7 75 126 126
84 8 0 0 12 40 87 57 58 49 14 2 1 16 19 76 26 10 34 11
6 19 113 110 16 8 26 22 11 20 126 126 28 33 19 5 8 50 96 30
28 7 0 0 9 54 32 71
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3
13 0 0 0 5 0 0 3 11 0 0 2 11 13 1 6 24 8 0 0
3 11 8 11 35 26 14 3 0 5 11 59 117 50 30 1 10 0 0 17
67 29 72 92 36 81 64 77 25 4 0 0 4 81 54 97 40 17 18 4
8 78 55 5 14 70 98 9 15 49 12 0 4 31 211 140 10 65 89 26
2 0 1 6 2 55 41 42 9 0 0 0 4 96 106 10 0 0 0 1
46 194 64 0 0 0 6 12
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 13 0 0 0
0 0 0 3 15 1 0 4 4 0 0 1 34 11 0 0 15 18 3 8
53 41 22 2 3 8 8 13 101 55 35 0 0 4 11 58 70 36 88 72
4 0 0 8 35 6 0 0 48 95 82 104 57 28 27 3 2 85 67 128
10 79 94 5 4 67 71 7 3 31 198 84 6 39 22 0 2 0 0 5
10 61 109 38 7 0 0 0 0 55 54 54 0 0 0 0 1 77 133 9
0 0 5 5 27 139 84 0
 
Zuletzt bearbeitet:

fastjack

Top Contributor
Nein, die landen auf dem Heap. Wenn ein "line" Objekt nicht mehr benutzt wird, wird es irgendwann, whl. nach einem Schleifendurchlauf bei dir, vom GC abgeräumt.
Dein Problem sind die 18 Mio Zeilen, die dann auch irgendwann in die Listen wandern. Versuch doch mal häppchenweise die Daten zu verarbeiten, also immer 1000, 10000 oder so...
 
S

SlaterB

Gast
gibt es schon einen OutOfMemoryError?
wenn nicht, dann reicht doch der Speicher, wann die nicht benötigten Strings aufgeräumt werden kann Java selber entscheiden,
notfalls erst dann wenn Platz gebraucht wird,
solange du zu 100% die CPU mit deiner Schleife usw. belastest ist es ja nicht unbedingt nötig, diese Arbeit für evtl. unwichtige Aufräumarbeiten, die auch später noch in Pausen passieren können, zu unterbrechen
 

vimar

Bekanntes Mitglied
es gibt keinen outofmemory derzeit weil ich die trainingsmenge verringern musste genua damit ich keinen outofmemory bekomme + musste extra ram kaufen gehen damit ich überhaupt was machen kann.....

kmeans4threads.jpg


aber wenn ich meine richtige trainigsmenge benutzen will bräuchte ich an die 12-13 GB ram und mein mainboard unterstützt garnicht soviel ram.

deswegen muss ich das unbedingt lösen -.-.-.- ich les nochmal was ihr allegeschrieben habt -.-


hier von visualvm:

visualvm1.jpg
 
Zuletzt bearbeitet:
S

SlaterB

Gast
die Object[] kommen sicherlich von den vielen ArrayLists, machen in dem Screenshot einen bedeutenden Anteil aus,
viel mehr als die Strings,

die ArrayLists gehen auch nicht weg da du sie ja merkst, wie schließt du aus dass die das Problem sind?

Integer sind nur relativ wenige, da die zum Glück bei Integer.valueOf() gecacht werden bis 128,
verwende testweise new Integer(), dann dürfte sich dein Speicher-Bild nochmal kräftig verändern,

falls du auch größere Zahlen hast, aber dennoch nur 1000 verschiedene, wäre ein eigener Cache ein Speicher-Wunder,
zumindest die 80 MB aktuell ließen sich noch zu 99% drücken

-------

was man da sonst optimieren kann ist vorerst nicht so leich zu sehen,
mit einfachen int[] wärst du sicher besser dran wie auch immer du das irgendwo einbauen kannst,

nicht zig Millionen bis Milliarden Daten gleichzeitig im Speicher zu halten ist der schon genannte Standardtipp,
wozu braucht du sie, kannst du sie nicht direkt bei der Berechnung laden?
 
Zuletzt bearbeitet von einem Moderator:

fastjack

Top Contributor
Starte mal das Programm mit GC-Ausgaben. Ich würde auch mal nach XXX-Läufen die GC selber mal triggern (System.gc()) und dann mal einfach schaun, was passiert. Ob überhaupt was da ist zum abräumen und so...
 

vimar

Bekanntes Mitglied
Starte mal das Programm mit GC-Ausgaben. Ich würde auch mal nach XXX-Läufen die GC selber mal triggern (System.gc()) und dann mal einfach schaun, was passiert. Ob überhaupt was da ist zum abräumen und so...

ich habe das gerade mal gemacht vielen dank! :

Java:
filecount++;
       if(filecount%5 == 0){
        System.gc();
           System.out.println("aufgeräumt -.-");
        }


hab somit halbwegs den speed von voher und das ganze String gedöns verschwindet auch :) :) :)

vielen dank nochmal an alle!
 
G

Gast2

Gast
Java:
        System.gc();
           System.out.println("aufgeräumt -.-");
Der System.gc() Aufruf stellt nicht sicher dass die JVM tatsächlich den GC gestartet hat, das ist lediglich ne bitte. Selbst wenn dann Speicher freigemacht wird würde ich den Aufruf trotzdem rausnehmen. Die JVM startet den GC schon wenns mal eng wird mitm Speicher.
 

vimar

Bekanntes Mitglied
eike ich habe von dieser theorie gehört und ich kann nur im selbsttest feststellen: es mag allgemein sein, aber scheinbar kriegt die vm es nicht gebacken bei 18 Mio Strings. ich bin auch deiner meinung aber der selbe umfang an inout ohne selbstständiges aufrufen von system.gc() endet mit einem outofmemory error. jedesmal wenn der heap voll ist seh ich im output auch wegen der latenz dass der gc versucht aufzuräumen - schafft es auch - aber irgendwie schaufelt der dann nur ca 300 MB frei. nach dem motto:
schaufel 300 mb frei, lade alles voll, schaufel 300MBfrei, lade alles voll, lade zuviel -> heapsizeerror.
es werden nicht die gesamten stringobjekte gelöscht die gelöscht werden sollten.

durch den manuellen aufruf löscht der jedenfalls derzeit wenigstens konsequent immer diese 300-500MB die überhaupt anfallen und es kommt niemals zu dieser 18 Mio Stringobjekte ansammlung.

in der theorie stimme ich dir vollkommen zu. allerdings sehe ich in der praxis dass der gc nur mist macht wenn man den nicht "bittet".
 
Zuletzt bearbeitet:
S

SlaterB

Gast
du schaffst also eine Exception zu bekommen, die nur durch gc()-Aufruf dann weg geht?
interessante Info, hat mich schon länger interessiert, aber hier im Forum war glaube ich (länger) kein Beispiel zu sehen,

deins ist freilich für andere auch nicht nachprüfbar, aber immerhin eine Aussage
 

vimar

Bekanntes Mitglied
slaterB ich bin kein java-experte wie ihr alle. ich kann nur aus den praxisbeispiel sagen was ich sehe.

ich sehe einen gc der sich nicht die mühe macht wenn der heap voll ist, einfach mal richtig zu schauen, sondern einfach nur "ein bissl" freimacht und auf gutes wetter hofft. und effektiv erscheint mir das auch nicht, 6 GB vollzuschaufeln, davon 3 GB StringObjekte die keiner mehr braucht, und gc macht mal nur schnell 300MB frei die dann im nächsten durchlauf sowieso wieder voll sind wodurch der gc mehr oder weniger sich sowieso aufrufen muss ohne ende.

durch einen System.gc() in den pausen (in meinem fall vor der erstellung der nächsten parserinstanz bzw mod 5 -> nach 5 parserinstanzen) schaufelt system.gc() halt seine was weiss ich 300-500MB frei die er sonst scheinbar auch nur hinkriegt. vllt kann man aber den "grad der freischauflung" irgendwie über diese vm optionen freeratio oder so bestimmen ich weiss es nicht bin dafür einfach zu wenig bewandert in java.


nach der theorie über System.gc() "bitte ich" dass System.gc() überhaupt passiert und es gäbe wohl keine garantie. kann es sein dass sich hier was geändert hat in java 7? nach visualvm ignoriert er NIE meine "Bitte".

Java HotSpot VM Options

-XX:MaxHeapFreeRatio=70 Maximum percentage of heap free after GC to avoid shrinking.
-XX:MinHeapFreeRatio=40 Minimum percentage of heap free after GC to avoid expansion.

die beiden hatte ich drin, aber hat scheinbar nix genutzt!
 
Zuletzt bearbeitet:

vimar

Bekanntes Mitglied
Hier steht nochmal genau warum eine OutofMemory Exception kommt!:

5.2.3 Out-of-Memory Exceptions

The throughput collector will throw an out-of-memory exception if too much time is being spent doing garbage collection. For example, if the JVM is spending more than 98% of the total time doing garbage collection and is recovering less than 2% of the heap, it will throw an out-of-memory expection. The implementation of this feature has changed in 1.5. The policy is the same but there may be slight differences in behavior due to the new implementation.


also ziemlich logisch, bei 18 Mio StringObjekten braucht der GC scheinbar zu lange UM alles zu löschen, er würde es schaffen aber weil er da zu lange braucht kommt ein outofmemory exception

nur wens interessiert :D
 

fastjack

Top Contributor
@vimar Dein Beispiel ist schon richtig

Whl. wird der Speicher so schnell voll, daß die GC gar nicht mehr zum Zug kommt. Das man sich nicht darauf verlassen soll, daß die GC auch manuell ausgeführt wird ist schon klar, allerdings wird sie bei den meisten Implementierungen auch ausgeführt (Oracle selbst als Beispiel, auch OpenJDK), wenn man sie manuell triggert ;) Das ist seit mindestens Java 1.4 so der Fall.
 
S

SlaterB

Gast
nur weil das in einer Klasse StreamTokenizer steht, muss da nicht heißen, dass dort nicht intern auch ne Menge Strings anfallen,
stimmt aber wohl, sieht effizienter aus,
selber hätte man dann auch mit chars rechnen können
 
S

Spacerat

Gast
Natürlich verwendet der StreamTokenizer auch Strings aber für Zahlen halt double. Und mit [c]tokenizer.ordinaryChars(0, 255); tokenizer.parseNumbers();[/c] ist's mit der String-Erzeugung vollkommen vorbei und man bekommt nur noch Zahlen. Diese müssen nur noch in ints gewandelt werden und per Autoboxing in die List<Integer> eingefügt werden.
Und wenn man noch einen Draufsetzen will, speichert man die ints nicht in einer List<Integer> sondern in einem java.nio.IntBuffer mit dem Attribut direct. Da muss man allerdings aufpassen, wann man ihn vergrössern muss, weil diese Buffer sind leider nicht dynamisch.
 

irgendjemand

Top Contributor
ich beziehe mich mal auf das bereits gesagte : ist es sinnvoll so viele daten GLEICHZEITIG im RAM zu haben ...
ich beziehe mich jetzt hierbei nur mal auf die geparseten listen ...

vielleicht mal ein "standard" beispiel um zu zeigen das es eigentlich sinnlos ist selbst so viele geparsete daten im RAM zu haben

wenn man mit 4 Threads arbeitet kann ein 4kern-cpu 4 berechnung zeitgleich ausführen ...
wenn man mit 8 Threads arbeitet kann ein 2kern-cpu trotzdem nur 2 berechnung gleichzeitig ausführen

ich denke hier sieht man schon : um den sinn hinter deiner daten-haltung zu begründen müsstest du alles gleichzeitig machen : daten einlesen , prasen , weiterverarbeiten *was auch immer du damit vorhast* ergebnisse wieder rausschreiben ... und was nicht noch ...
damit sich das dann bei der datenmenge auch überhaupt lohnt bräuchtest du schon ein paar dutzent cpu-cores die alle relativ hoch getaktet sind , extrem viel und schnellen RAM und vor allem auch gute anbindung an daten-quelle und -ziel *in der regel platten ... *die ausrede : übers netz ... zählt hier nicht da schließlich auch der server und vor allem das netz selbst mit dieser datenflut klarkommen müssten*


daraus kann man ableiten : wenn du jetzt jedes file einzeln einliest ... und das auch nur zeile für zeile ... und dann auch immer nur eine zeile gleichzeitig parset ... warum musst du dann zig millionen datensätze im RAM speichern ? verarbeite die daten doch dierekt nach dem einlesen *soweit möglich* und schreibe die ergebnisse wieder raus auf platte in ein file ...

mit dieser methode könnte man sogar mir standard-VM *glaube 64MB oder was das waren ?* die aufgabe bewältigen ... und das auch gar nicht mal so viel langsamer als mit der methode die du atm verwendest ... dafür aber deutlich resourcen-schonender was die wiederum mehr spielraum für parallelisierung lässt ...
du könntest dann z.b. 2 oder mehr instanzen deines programmes laufen lassen und halt nur unterschiedliche daten verarbeiten *z.b. instanz 1 verarbeitet alles aus ordner 1 usw ...*

wie gesagt : ich kann mir halt einfach nicht vorstellen das du deine aber millionen von geparsten daten überhaupt alle gleichzeitig im RAM brauchst ...
und wenn du dich danach richtest ... also wirklich nur die daten im RAM hast mit denen du in diesem moment auch wirklich arbeitest ... dann passieren dir solche fehler nicht ...
denn alles erstmal in den RAM laden ... stück für stück ... nur um dann mit diesen daten auch wieder nur stück für stück weiter zu arbeiten ... und dann noch mehr daten im RAM zu haben nur um dann vielleicht eine ausgabe zu erzeugen ... die man an sich auch genau so gut wieder in ein file schreiben könnte ... das ist einfach ein konzeptfehler ... und kann man so eben auch nur umsetzen wenn man eben diese riesigen resourcen hat ...

*z.b. 8C/16T XEON , 64GB RAM und 2 nVid karten für CUDA *also anstatt auf der CPU halt auf der GPU rechnen* , großes RAID ... dann kann man z.b. mit der power des CPU alles von den platten in den RAM schieben und von da die eigentlichen *vermutlich numerischen* berechnung von den grakas erledigen lassen ...
aber da du ein solches monster nun mal nicht hast ... musst du dich mit dem abfinden was du hast ... und entsprechend dein programm und dessen arbeitsweise an das vorhandene system anpassen ... und nicht so lange dein system aufrüsten bis dein konzeptionell völlig aus dem ruder gelaufenes programm laufen zu lassen ...
 

vimar

Bekanntes Mitglied
irgendwas auf disk schreiben frisst einfach nur zeit, und ich schreibe sicherlich nicht einzeln den kram auf disk. ich könnte es. ich kann es auch sein lassen. ich will meine nested arraylist mit meinen 300.000 128-dim vektoren einfach komplett im ram haben weil der kmeans algo sowieso schon ewig braucht und ich ne iterationsgrenze setzten musste. jetzt noch disk read und write muss da einfach nciht sein.
 
S

Spacerat

Gast
Ja isses denn? ArrayList... Schnik Schnak...
Java:
import java.io.FileReader;
import java.io.StreamTokenizer;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
 
public final class StreamSearch
{
	public static void main(String[] args)
	throws Throwable
	{
		StreamTokenizer st;
		IntBuffer ib = ByteBuffer.allocateDirect(4000).asIntBuffer();
		IntBuffer tmp;
		while((st = getNextFile()) != null) {
			st.ordinaryChars(0, 255);
			st.parseNumbers();
			int token;
			do {
				token = st.nextToken();
				ib.put((int) st.nval);
				if(!ib.hasRemaining()) {
					tmp = ByteBuffer.allocateDirect(ib.capacity() * 8).asIntBuffer();
					ib.flip();
					tmp.put(ib);
					ib = tmp;
				}
			} while(token != StreamTokenizer.TT_EOF);
		}
	}

	private static StreamTokenizer getNextFile()
	throws Throwable
	{
		StreamTokenizer st = new StreamTokenizer(new FileReader("./test.txt"));
		return st;
	}
}
In so einen Buffer passen 536870911 Intwerte... vorrausgesetzt man hat genug Speicher. Im Beispiel ist der Buffer alledings nicht begrenzt und das Proggi liefert eine Exception, wenn die Zahl überschritten wird. Mit [c]get(int index)[/c] und [c]put(int index, int value)[/c] lässt sich darauf sogar ArrayList ähnlich zugreifen. Wenn einem nun auch noch Feld-Schrittweiten (Strides) für mehrdimensionale Arrays aus Assembler oder C++ geläufig sind, gibt es keine Probleme mehr mit Speicher oder gar Performance, weil der StringTokenizer mit dieser Konfiguration bis auf ein Bytearray kein einziges Objekt mehr instanziert. Ferner liegt der Buffer auch noch ausserhalb des Heaps (im Hauptspeicher) und man muss die JVM nicht mal mit mehr zugewiesenem Speicher starten. Versuch' mal, was draus zu machen.
[EDIT]Eins noch: Der IntBuffer kann hier maximal den halben Hauptspeicher bzw. überhaupt nur Integer.MAX_VALUE Bytes (2GB) belegen. Sofern man nur 4GB im Rechner hat, empfiehlt es sich ihn gleich mit Integer.MAX_VALUE zu allocieren und auf die dynamische Vergrössereung zu verzichten.[/EDIT]
 
Zuletzt bearbeitet von einem Moderator:

irgendjemand

Top Contributor
irgendwas auf disk schreiben frisst einfach nur zeit, und ich schreibe sicherlich nicht einzeln den kram auf disk. ich könnte es. ich kann es auch sein lassen. ich will meine nested arraylist mit meinen 300.000 128-dim vektoren einfach komplett im ram haben weil der kmeans algo sowieso schon ewig braucht und ich ne iterationsgrenze setzten musste. jetzt noch disk read und write muss da einfach nciht sein.

auf die gefahr hin das ich mich wiederhole : wenn du ein solches vorhaben umsetzen willst musst du halt deine hardware um dein programm rumbauen ...

sry ... aber anders kann ich es nicht mehr ausdrücken ...
auch wenn es halt "einfach zeit frisst" wenn man halt nur die daten im RAM hat mit denen man gerade rechnet und den rest auf platte schreibt ... ist es dennoch die sinnvollere methode ... und auch eine die in der praxis deutlich häufiger anzutreffen ist als alles in schnellen RAM packen ...

oder was meinst du warum z.b. für hochkomplizierte rechnungen jahre dran gerechnet wird ... weil halt einfach die resourcen fehlen um eben alles im schnellen RAM zu haben und halbwegs intiligent parallel laufen zu lassen ...

wenn du also die anforderungen die du mit deinem programm an deine hardware stellst nicht erfüllen kannst brauchst du nun mal zeit ... da in der IT der grundsatz gilt : weniger zeit wird durch mehr resourcen erkauft ... und andersrum ... -> wenn du eins nicht erfüllen kannst musst du halt mehr vom anderen nehmen
 
J

JohannisderKaeufer

Gast
Java:
ArrayList<ArrayList<Integer>> AAO_kPointList;

Ich vermute mal das das letztendlich die 300.000 128-Dimensionalen Vektoren sind.

Wenn die größen schon feststehen, warum dann kein
Java:
int[][] aaoKPointArray = new int[300000][128];

Oder wenn die 128 feststehen dann eine List<int[]>
 

vimar

Bekanntes Mitglied
irgendjemand: du hast schon recht keine frage, nur ich habe die zeit nicht um zulange zu warten daher will ich das so -.-

johannes: 300.000 steht nicht fest, aber 128 schon. ich muss beizeiten mal dafür nen int array machen und den ganzen code dann anpassen. das ist auf jedenfall besser.

es geht auch "nur" um nen db aufbau. später braucht mein programm beim laden der dbs nicht viel ram. ich bin ehrlich gesagt einfach nur glücklich dass es überhaupt nun funktioniert. ^^
 

irgendjemand

Top Contributor
naja ... ob du es willst ist die eine sache ... nur ob du es umsetzen kannst die andere ...

der ganze thread läuft ja auf die tatsache hinaus das du durch das interne caching der VM in speicher-probleme rennst weil du die zeit nicht opfern willst / kannst um diese zu vermeiden ...

und da musst du halt genau die mitte treffen ... höchste performance bei niedrigster zeit ohne fehler ... klingt einfach ... ist aber verdammt schwer ... und manchmal ist der grad so schmal das man sich mit einzelnen bytes im nanosekundenbereich bewegt ...

mehr als dir sagen das du vielleicht ETWAS mehr zeit opfern solltest um das ganze etwas stabiler zu bekommen und am ende nicht in speicher-probleme zu rennen kann ich leider nicht ... und ich weis auch nicht in wie fern sich die VM tweaken lässt das der GC schneller und vor allem MEHR aufräumt ... aber bin der meinung erst in den letzten tagen bei nem ähnlichen problem ne kilometerlange command-line gesehen zu haben mit der wohl genau das problem was du hast teilweise lösbar sein soll ... aber da müsste ich jetzt auch noch mal suchen ...
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
kodela String kann nicht zu Pfad konvertiert werden Allgemeine Java-Themen 16
M Map<String,String>funktioniert nicht richtig Allgemeine Java-Themen 4
P String.replace() funktioniert nicht? Allgemeine Java-Themen 3
W String -> byte[] -> String - Sieht jemand was ich nicht sehe? Allgemeine Java-Themen 10
M Programm erkennt String aus .txt Datei nicht Allgemeine Java-Themen 3
M String lässt sich nicht Zusammenfügen Allgemeine Java-Themen 10
R Schlüsselworte "Throw new exception" gibt nicht den String als Fehlermeldung aus Allgemeine Java-Themen 2
D Java Error String kann nicht in Int umgewandelt werden Allgemeine Java-Themen 2
A Kann String nicht vergleichen (Android) Allgemeine Java-Themen 4
D Name eines Nicht-String Objekts ausgeben Allgemeine Java-Themen 4
P Datentypen String-Daten zu Byte-Zahlen konvertieren - Komme nicht weiter nach vielem versuchen :-/ Allgemeine Java-Themen 7
K String.replace funktioniert nicht Allgemeine Java-Themen 3
P Absatz im String / Excel / /n geht nicht Allgemeine Java-Themen 2
S Entfernen von allen Nicht-Buchstaben chars aus einem String ohne Regex..? Allgemeine Java-Themen 10
A String.split() funktioniert nicht richtig Allgemeine Java-Themen 4
Airwolf89 ReplaceAll, kann xml- Tag nicht aus String ausschneiden Allgemeine Java-Themen 3
G konstanter String[] laesst sich nicht in Annotation nutzen Allgemeine Java-Themen 2
M Übergebener String bearbeiten geht nicht. Allgemeine Java-Themen 4
Y PropertyMap: Zugriff über konkatenierten String klappt nicht Allgemeine Java-Themen 7
J MD5-Prüfsumme von ein und demselben String nicht gleich Allgemeine Java-Themen 3
O String NICHT vergleich Allgemeine Java-Themen 7
m@nu int zu Hex, aber nicht als String Allgemeine Java-Themen 4
P ReplaceAll ersetzt nicht bzw. möchte verketteten string Allgemeine Java-Themen 4
S [Base64] Encoding von String nicht korrekt Allgemeine Java-Themen 5
P String.split will nicht Allgemeine Java-Themen 3
V String[] wird nicht als Rückgabetyp vom Compiler akzeptiert! Allgemeine Java-Themen 6
OnDemand Java String in Hashmap als Key NULL Allgemeine Java-Themen 27
JAnruVA Datentypen Berechneten String-Wert in Double umwandeln um weiter zu rechnen Allgemeine Java-Themen 7
M String Allgemeine Java-Themen 10
M Suche nach String mit unbekannten characters Allgemeine Java-Themen 53
melaniemueller Einzelne Zeile aus einer txt Datei in einem String speichern Allgemeine Java-Themen 12
E Objekte in einen String packen und wieder laden Allgemeine Java-Themen 5
O String in Long Hexerdezimal umwandel Allgemeine Java-Themen 14
N String vergleichen. Allgemeine Java-Themen 27
SaschaMeyer Arbeitet String.split falsch? Allgemeine Java-Themen 4
M Switches ohne String Allgemeine Java-Themen 18
AmsananKING String Iteration Allgemeine Java-Themen 5
S Shuffle String aus if-clause Allgemeine Java-Themen 11
Besset Variablen Ist String = "" + int inordnung? Allgemeine Java-Themen 6
M Map <Long, String> zu Map<String, Long> Allgemeine Java-Themen 9
S String Encoding Verständnisproblem Allgemeine Java-Themen 22
N Prüfen, ob ein String 2x das selbe Zeichen hat Allgemeine Java-Themen 10
SaftigMelo Bug Fixen von String-spliten Allgemeine Java-Themen 8
Monokuma String List nach Zahlen und Worten sortieren Allgemeine Java-Themen 9
Kingamadeus2000 Alle mehrfach vorkommenden Buchstaben rekursiv aus einem String entfernen. Allgemeine Java-Themen 6
YohnsonM String - Aufteilung und Nutzung einzelner Chars Allgemeine Java-Themen 7
O Formatierte String ausgabe bei vier Variablen in einer Zeile Allgemeine Java-Themen 1
S String umbenennen: wie? Allgemeine Java-Themen 4
x46 String Format Fehler Allgemeine Java-Themen 2
S ISO 8601 -> getter / setter String Allgemeine Java-Themen 3
L String zu repräsentativen Wert Allgemeine Java-Themen 0
H Array mit dem Datentype String[] initializieren Allgemeine Java-Themen 7
L ArrayList mit String Arrays in ein Array umwandeln Allgemeine Java-Themen 1
L regex ganzer string? Allgemeine Java-Themen 2
L Ist ein string ein erlaubter variabel name? Allgemeine Java-Themen 2
Z JNA Cpp-DLL String Verwendung Allgemeine Java-Themen 2
A String auf Zahlen überprüfen Allgemeine Java-Themen 5
N String Array Eingabe Allgemeine Java-Themen 6
MiMa Datum von String zu LocalDateTime Allgemeine Java-Themen 8
R char aus String entfernen Allgemeine Java-Themen 10
LimDul Mittels Streams aus Strings A B C den String A, B und C machen Allgemeine Java-Themen 12
P einen public <Optinal String> in einer anderen Klasse mit einem Int vergleichen Allgemeine Java-Themen 2
S Ini Text aus String parsen Allgemeine Java-Themen 1
T String-Manipulation beim Ablauf in Eclipse und als JAR-File Allgemeine Java-Themen 8
Drachenbauer Wie kann ich das Wort "concrete" in einem String durch ein anderes Wort ersetzen lassen? Allgemeine Java-Themen 5
R Variablen String mit split-Funktion aufteilen Allgemeine Java-Themen 7
F Datei in String-Array einlesen Allgemeine Java-Themen 8
S Marker aus String ermitteln Allgemeine Java-Themen 5
T Objekt mit String und Int aus TxT Datei erstellen Allgemeine Java-Themen 23
M Bei String.format ein Komma statt einem Punkt ausgeben lassen Allgemeine Java-Themen 1
S MSSQL Exception & Connection String Allgemeine Java-Themen 19
B Bei Email: FW / AW... - Hilfe bei String suche Allgemeine Java-Themen 21
J String - Vergleiche Allgemeine Java-Themen 7
K Aus String zwei Jahreszahlen auslesen Allgemeine Java-Themen 18
Drachenbauer Wie kann eine vorgegebene Farbe über einen String erkannt werden? Allgemeine Java-Themen 11
G CSV in String Allgemeine Java-Themen 7
P String-Verschlüsselung - Frage zur Sicherheit Allgemeine Java-Themen 21
K Methodenaufruf mit String / String zu Objekt konvertieren Allgemeine Java-Themen 8
D Erste Schritte Fehler mit negativen und 0 Zahlen im String Allgemeine Java-Themen 6
Xge Replace x Zeichen aus String Allgemeine Java-Themen 2
coolian warum bekomme ich ein string index out of bounds exception Allgemeine Java-Themen 17
F In String 2 Buchstaben vertauschen Allgemeine Java-Themen 2
J Class Decompile als String (Procyon) Allgemeine Java-Themen 2
I Datentypen String in class sicher verwahren Allgemeine Java-Themen 17
J Falls der String ein "X" beinhaltet Allgemeine Java-Themen 2
T String mehrere Worte Allgemeine Java-Themen 2
D String Groß-/Kleinschreibung Allgemeine Java-Themen 2
D String und Klassenvariable Allgemeine Java-Themen 6
Aruetiise Funktion(y = mx+n) in String speichern und berechnen Allgemeine Java-Themen 9
C String in Objektnamen umwandeln Allgemeine Java-Themen 3
E Variablen Aus .txt ausgelesener string mit if() überprüfen? Allgemeine Java-Themen 2
L String-Schema-Aufspaltung Allgemeine Java-Themen 2
E String in Zahl umwandeln, ohne Befehl Integer.parseInt Allgemeine Java-Themen 3
L String splitten und multiplizeren Allgemeine Java-Themen 10
G String mit umbekannter länge splitten. Allgemeine Java-Themen 2
S Einzigartigen String in Datenbank finden und löschen Allgemeine Java-Themen 23
A Byte zu String Allgemeine Java-Themen 4
B Von String zu <Objekt> ||Speichern/Laden Allgemeine Java-Themen 17
T Komplexitätsoptimierung String vergleich Allgemeine Java-Themen 4
heinz ketchup String im JLabel ausgeben und erneuern Allgemeine Java-Themen 6

Ähnliche Java Themen

Neue Themen


Oben