irgendwas frisst bei mir unmengen speicher.. muss ca 400 textfiles parsen und alle in einer riesigen arralist speichern... scheinbar hier 7 GB.. wollte daher die werte auf byte runterbrechen... oder fressen die ganzen parserinstanzen soviel? kann das?
zum "unsigned" machen, aber das ist eher als hack drumherum zu betrachten und nicht als eine schöne Lösung. Es kommt drauf an was du damit bezwecken willst.
P.S. Du kannst z.B. mit VisualVM nachschauen, was so viel Speicher frisst. Vermutlich sind es aber die Strings.
In einer ArrayList stehen Objekte - da ist es fast egal, ob das ein short, int oder byte ist. Kannst du die daten als byte[] oder ggf. short[] array speichern?
Die normale Java-VM erweitert die kleinen Ganzzahltypen intern eh zu int. Da spart man also keinen Speicher. Was aber was bringt, ist sich nicht auf Autoboxing zu verlassen und auf gar keinen Fallnew Integer zu benutzen, sondern beim adden die Factory-Methode Integer.valueOf zu verwenden. Das wird intern gecached, sodass bei gleichen Werten die Referenz auf ein einziges Objekt zeigt und nicht jedes Mal ein neues angelegt wird. Wobei ich mir ehrlich gesagt nicht sicher bin, dass Autoboxing das nicht evtl. genauso macht.
Sie erweitert diese Typen - zum Rechnen, und bei einzelnen lokalen Variablen oder Fields. Trotzdem braucht ein
new int[1000];
oder
new Object[1000];
etwa vier mal so viel Speicher wie ein
new byte[1000];
Bei ArrayList kommt noch dazu, dass es "bestimmte Größen ""nicht gibt""": Wenn eine ArrayList mit 1000000 Einträgen voll ist, wird intern ein Array mit 1500000 Elementen erstellt - auch wenn man vielleicht nur 1000001 Elemente braucht.
So ganz stimmt das nicht: Soweit ich weiß kann man eine [c]ArrayList[/c] auch in kleineren Schritten durch Aufruf von [c]ensureCapacity[/c] vergrößern.
Konnte/Wollte Marco nicht glauben und habe mal Testcode geschrieben;
Java:
publicfinalclassMain1{privatestaticfinalint ARR_LENGTH =10000000;/**
* @param args
*/publicstaticvoidmain(String[] args )throwsThrowable{finalRuntime runtime =Runtime.getRuntime();System.out.println(runtime.freeMemory());finalboolean[] arr =newboolean[ARR_LENGTH];// final byte[] arr = new byte[ARR_LENGTH];// final short[] arr = new short[ARR_LENGTH];// final int[] arr = new int[ARR_LENGTH];System.out.println(runtime.freeMemory());}}
Habe jeweils den gewünschten Datentyp auskommentiert und siehe da, Marco hat Recht. boolean und byte haben denselben Verbrauch, danach steigt es jeweils an.
So ganz genau kann man es nicht steuern. Es wird der größere Wert von übergebenem Parameter verglichen mit der Summe aus aktueller Größe plus doppelter aktueller Größe des internen Arrays genommen. Das ganze passiert in der privaten Methode
Und um nochmal auf die Ursprungsfrage zurück zu kommen. Basierend auf den Erkenntnissen in diesem Thread ist ein Array von Primitives die effizienteste Wahl. Da Arrays eine fixe Länge haben und Du sicher vor dem Einlesen nicht weißt, wie viele Elemente Du genau brauchst, empfehle ich eine Hilfsklasse (z.B. PrimitiveByteList oder PrimitiveShortList), die einen Array von Primitives als Instanzvariable hält. Die Hilfsklasse muss sich dann beim Adden um das Resizing des Arrays und anschließendes Arrays.copyOf kümmern. Als Vorlage hierfür kannst Du Dir den Quellcode von ArrayList anschauen.
TByteArrayList (Trove 3.0.0) , aber das löst das Vorzeichenproblem noch nicht. Allerdings wäre es leicht, den Code zu klauen und entsprechend umzustricken.
irgendwas frisst bei mir unmengen speicher.. muss ca 400 textfiles parsen und alle in einer riesigen arralist speichern... scheinbar hier 7 GB.. wollte daher die werte auf byte runterbrechen... oder fressen die ganzen parserinstanzen soviel? kann das?
was macht denn Integer.valueOf(xxx), was new Integer(xxx) nicht macht? Mal abgesehen von der Byte-Optimierung, also den Zahlen -128 bis +127 die im IntegerCache landen Genau, gar nix
was macht denn Integer.valueOf(xxx), was new Integer(xxx) nicht macht? Mal abgesehen von der Byte-Optimierung, also den Zahlen -128 bis +127 die im IntegerCache landen Genau, gar nix
aber genau das ist kein Gegenargument Integer.valueOf nicht zu nehmen. Mit valueOf bekommt man entweder gecached oder neue Instanz, mit new immer eine neue Instanz. Daher sollte man immer valueOf nehmen.
Da der TO nach Werten bis 200 gefragt hat, ist die Chance, die Cache-Funktionalität nutzen zu können bei mehr als 50%. Insofern ist das doch ein valider Hinweis, oder nicht? Ansonsten schreiben sogar die Jungs von Su.., äh Oracle in den API-Docs, dass valueOf dem Konstruktor vorzuziehen ist.
Einerseits: Natürlich. Andererseits... wenn jemand eine ("große") Datei mit
Java:
ArrayList<Byte> data =...while(...) data.add(readByteFromFile());
einliest, rollen sich mir aus mehr als einem Grund die Fußnägel hoch :autsch: Unabhängig davon, ob was anderes vielleicht auch noch unnötig Speicher frißt.
1. alle <Integer> Arraylists als <Short> zu machen -> brachte mir nichts.
2. anstatt new Integer Integer.valueOf -> brachte mir auch nichts.
Der Ram ist immernoch voll wie man hier unschwer erkennt -.-
Der Profiler von netbeans ist mehrfach abgestürzt (komplett netbeans keine rückmeldung bei soviel GB - komisch).
Ich habe auch in einem anderem Thema von dir gesagt: es könnte einfach sein, dass du nun mal viel Speicher brauchst. Es kommt stark auf deine Vektor-Darstellung an, idR sind es keine Listen, sondern Maps.
Das ... hätte ich dir auch vorher sagen können ... ein Short braucht genausoviel wie ein Integer oder Byte, und auch eine List<Byte> ist nicht kleiner als eine List<Integer>. Der Unterschied besteht nur bei primitiven arrays: byte[] statt int[]...
Mit dem Taskmanager (und auch noch Windows) ist das etwas schwammig. Nimm einen Java-Profiler, dann bekommst Du exakte Ergebnisse. Wer weis schon, was bei Windows, hier gerade CPU oder RAM frißt.
Richtig, StringTokenizer ist extrem langsam. Benutze Scanner und eine Regex. Wenn du's richtig machst, solltest du dir auch gleich das extra einlesen als String sparen können.
was macht denn Integer.valueOf(xxx), was new Integer(xxx) nicht macht? Mal abgesehen von der Byte-Optimierung, also den Zahlen -128 bis +127 die im IntegerCache landen Genau, gar nix
[OT]Nur ein Random Fact und trägt jetzt zwar nicht zur Lösung bei, aber ich bin selbst vor kurzem über diese Property Einstellung gestoßen, die bei Oracle/Sun JDK (ab 6uIrgendwas) funktioniert: