# Große ArrayListen



## ste (22. Sep 2007)

Hallo,

ich habe folgendes Problem: In meinem Programm muss ich sehr große ArrayListen handeln. Ich habe eine ArrayList in der ca. 1 Mio. Punktobjekte mit ID und Koordinaten gespeichert werden. Zusätzlich benötige ich noch eine ArrayList mit ca. 3 Mio. Linienobjekten mit Start- und Endknoten. 
Die Punkte machen keine Probleme, aber wenn ich die ArrayList mit den 3 Mio. Linien anlege, bekomme ich eine "Out of memory" Exception. (ich war eigentlich auch nicht überrascht, denn irgendwann musste das ja passieren  :?)
Gibt es irgendeine Möglichkeit das ganze Platzsparender anzulegen, oder temporär auf die Festplatte auszulagern, oder vielleicht ganz was anderes?
Denn zusätzlich möchte ich aus den Informationen über die Punkte und Linien noch Dreiecke berechnen, die auch noch irgendwo zwischengespeichert werden müssen. 

Kennt jemand eine Lösung mit der man so große Datenmengen behandeln kann,um sie dann auch noch mit angemessener Berechnungszeit weiter zu verarbeiten?


----------



## Marco13 (23. Sep 2007)

Bill Gates soll ja mal gesagt haben: "No one will need more than 640 kilobytes of memory for a personal computer.". Wie viel RAM hast du? Ein Gigabyte? oder 2 oder 4? Jedenfalls genug, um 1 Million Punkte zu Speichern (1 Objekt: ca. 24 bytes, ID: 4 bytes, 3*double-Koordinaten: 3*8 bytes, insgesamt ca. 50 bytes d.h. ca. 50 MB) Selbst wenn die 3 Millionen Linien nochmal jeweils 100 byte brauchen sollte das kein Problem sein.

Schon mit 
java -Xmx*1200m* MeinProg 
gestartet, und z.B. 1.2 GB Speicher bereitgestellt?

Trotz allem solltest du - falls möglich - die ArrayLists mit der gewünschten Größe initialisieren, also 

*NICHT*
ArrayList a = new ArrayList();
for (int i=0; i<3000000; i++) a.add(new Line(...));

sondern
ArrayList a = new ArrayList(*3000000*);
for (int i=0; i<3000000; i++) a.add(new Line(...));

Sonst dauert das Einfügen viel länger, und es wird u.U. VIEL zu viel Speicher allokiert.


----------



## byte (23. Sep 2007)

Oder wenn die Größe vorher nicht bekannt ist, alternativ eine LinkedList benutzen.


----------



## ste (24. Sep 2007)

Vielen Dank für eure Antworten.

Also, ich hab 1GB RAM. Es geht zwar noch was fürs Betriebssystem drauf, und diverse andere kleine Dinge, aber das was übrig bleibt sollte eigentlich ausreichen.

Die ArraListen habe ich natürlich vorher initialisiert, das ständige Umkopieren würde bei der Anzahl der Einträge einfach zu lange dauern.

Ich bekomme folgende Exception beim Initialisieren der 3 Mio. ArrayList für die Linien:

Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space

Irgendwie muss man das Problem doch lösen können, denn es gibt ja auch andere Programme, die große Datenmengen verarbeiten.  ???:L


----------



## Marco13 (24. Sep 2007)

```
import java.util.*;

class ArrayListTest
{
    public static void main(String args[])
    {
        ArrayList a = new ArrayList(10000000);
        System.out.println("Done.");
    }
}
```

10 Millionen Einträge geht bei mir. Mit -Xmx1300m gehen sogar 30 Millionen (was bei 1GB aber nicht viel bringt). Kannst ja ggf. auch mal einen LinkedList testen (obwohl die sicher noch mehr Speicher braucht, als eine ArrayList).


----------



## kopfsalat (24. Sep 2007)

Beim Start der JVM kannst du den maximalen Speicherbedarf angeben, den die JVM nutzen darf. Standardmäßig ist das 64MB.
Wie Marco schon beschrieben hat kannst du das erhöhen, z.B. auf 512MB durch:


```
java -Xmx512m MeinProg
```


----------



## ste (24. Sep 2007)

Danke, ich werds gleich mal ausprobieren...


----------



## ste (24. Sep 2007)

Das mit dem Speicherplatz reservieren hat nicht geklappt. Wenn ich 1024 MB reserviere, dann fliege ich noch früher mit folgender Fehlermeldung raus: _Not enough storage is available to process this command at sun.nio.ch.FileChannelImpl.map0_


----------



## maki (24. Sep 2007)

Dann reservier doch weniger Speicher


----------

