ich brauche einen Ersatz für die Java Collections, da ich große Datenmengen dynamisch im Speicher Verwalten muss und die Java internen Collections nur Objekte halten können. Das Problem ist, dass mit den Java Standard Klassen z.B. 60Byte für einen Integer draufgehen, der eigentlich nur 32Bit Informationen enthält.
Vlt. mal Source, um zu verdeutlichen, was ich meine:
Runtime runtime = Runtime.getRuntime(); // Runtime Objekt, das die verwendete Speichermenge auslesen kann int i; LinkedList blubb = new LinkedList(); // Die original LinkedList aus java.utils runtime.gc(); // Runtime Objekt Momentane Werte auslesen lassen System.out.println("Speicherverbrauch vorher: " + (runtime.totalMemory()- runtime.freeMemory())); // Den verwendeten Speicher ausgeben for (i = 0; i < 60; i++) { blubb.add(new Integer(i)); // 60 Integer Objekte in der Liste ablegen } runtime.gc(); // Runtime neue Werte auslesen lassen System.out.println("Speicherverbrauch nachher: " + (runtime.totalMemory() - runtime.freeMemory())); // Den jetzt verwendeten Speicher ausgeben
Gibt bei mir wieder:
Speicherverbrauch vorher: 302272 Speicherverbrauch nachher: 306216
Macht 3944 Byte Differenz, nachdem 60 Integer angelegt wurden, also etwa 60 Byte pro Integer (stark abgerundet). Ich habe schon testweise probiert, selbst eine stark vereinfachte Liste zu erstellen mit einem Iterator Objekt, dass direkt den primitiven Datentyp int hält:
public class listtest { class Iterator { int i; Iterator next; } private Iterator head; private Iterator current; public listtest() { head = new Iterator(); current = head; } public void add(int i) { if (current.next == null) current.next = new Iterator(); current = current.next; current.i = i; } public int next() { if (current.next != null) current = current.next; return current.i; } public void rewind() { current = head; } }
Aber selbst so komme ich nicht unter 40Byte pro integer weg.
Das kann es aber nicht sein. Ich will ein Programm schreiben, dass Audiodaten verarbeitet und ich kann nicht bei einer Abtastrate von 8000 Samples pro Sekunde (und mehr) zwischen 40 und 60 Byte Speicher für jeden Sample draufgehen lassen - vor allem, da die eigentlichen Samples nur 16Bit quantisiert sind (32 Bit Integer nehme ich, weil ich im Laufe der Berechnungen, die ich damit anstelle, mehr als den 16Bit Zahlenraum brauche). Auf primitive Arrays (alla int [] bla = new int [60]) zurückzugreifen, kommt leider nicht in Frage, das wäre sinnloser Rechenaufwand beim Löschen und Verschieben von Zahlen.
Jetzt gibt es ja Libraries, wie PCJ, die Collections für primitive Datentypen anbieten. Allerdings habe ich Probleme, den stark abstrakten Code davon nachzuvollziehen (PCJ wurde extrem generisch programmiert und auf etliche Dateien aufgeteilt, sodass man den Überblick im Code sehr schnell verlieren kann). Das, was PCJ anbietet, ist mir auch zu viel, ich würde mir lieber etwas schlankeres selbst schreiben. Könnte mir jemand sagen, wie ich ein Collection Objekt für primitive Datentypen so in Java realisieren kann, dass nicht gleich etliche Byte für sinnlosen Overhead verschwendet werden? Gäbe es in Java ein Pointerverhalten, wie in C/C++, dann wäre es ja kein Problem, aber so bin ich leicht ratlos. Irgendeine Lösung muss es ja geben... ich kann mir nicht vorstellen, dass alle Javaprogramme, die dynamische Datenstrukturen brauchen, nur mit Wrapperklassen und massig sinnlosem Overhead arbeiten.
Vielen Dank für die Hilfe,
Fenix
Dieser Beitrag wurde von Fenix bearbeitet: 18. August 2007 - 16:44