it-swarm.com.de

Java Heapspeicher zu wenig Speicherplatz

Meine Anwendung belegt derzeit ziemlich viel Speicher, da sie physikalische Simulationen ausführt. Das Problem ist, dass konsistent bei der 51. Simulation Java) normalerweise einen Fehler auslöst, weil nicht genügend Speicherplatz vorhanden ist (mein Programm führt schließlich Tausende von Simulationen aus).

Gibt es überhaupt eine Möglichkeit, den Heap-Speicherplatz nicht nur zu vergrößern, sondern mein Programm so zu ändern, dass der Heap-Speicherplatz nach jedem Durchlauf gelöscht wird, sodass ich eine beliebige Anzahl von Simulationen ausführen kann?

Vielen Dank

-bearbeiten-

Danke Leute. Es stellte sich heraus, dass die Simulatorsoftware die Informationen nicht nach jedem Lauf löschte und ich diese Läufe alle in einer Arrayliste gespeichert hatte.

47
randomafk

Es gibt keine Möglichkeit, den Heap programmgesteuert dynamisch zu vergrößern, da der Heap beim Starten der Java Virtual Machine zugewiesen wird.

Sie können diesen Befehl jedoch verwenden

Java -Xmx1024M YourClass

um den Speicher auf 1024 zu setzen

oder Sie können eine min max

Java -Xms256m -Xmx1024m YourClassNameHere
36

Wenn Sie viel Speicher verwenden und auf Speicherverluste stoßen, möchten Sie möglicherweise überprüfen, ob Sie eine große Anzahl von ArrayLists oder HashMaps mit jeweils vielen Elementen verwenden.

Ein ArrayList wird als dynamisches Array implementiert. Der Quellcode von Sun/Oracle zeigt, dass beim Einfügen eines neuen Elements in ein vollständiges ArrayList ein neues Array mit der 1,5-fachen Größe des ursprünglichen Arrays erstellt und die Elemente kopiert werden. Dies bedeutet, dass Sie möglicherweise bis zu 50% des Speicherplatzes in jedem verwendeten ArrayList verschwenden, es sei denn, Sie rufen dessen trimToSize -Methode auf. Oder noch besser: Wenn Sie die Anzahl der Elemente kennen, die Sie zuvor einfügen werden, rufen Sie den Konstruktor mit der Anfangskapazität als Argument auf.

Ich habe den Quellcode für HashMap nicht sehr sorgfältig untersucht, aber auf den ersten Blick scheint es, dass die Array-Länge in jedem HashMap eine Zweierpotenz sein muss, was es zu einer weiteren Implementierung einer Dynamik macht Array. Beachten Sie, dass HashSet im Wesentlichen ein Wrapper um HashMap ist.

19
unkx80

Es gibt eine Vielzahl von Tools, mit denen Sie dieses Problem diagnostizieren können. Das JDK enthält JVisualVM , mit dem Sie eine Verbindung zu Ihrem laufenden Prozess herstellen und zeigen können, welche Objekte möglicherweise außer Kontrolle geraten. Netbeans ist von einem Wrapper umgeben, der ziemlich gut funktioniert. Eclipse hat den Eclipse Memory Analyzer, den ich am häufigsten verwende. Er scheint mit großen Dump-Dateien etwas besser umzugehen. Es gibt auch eine Befehlszeilenoption - XX: + HeapDumpOnOutOfMemoryError , mit der Sie eine Datei erhalten, die im Grunde genommen eine Momentaufnahme Ihres Prozessspeichers ist, als Ihr Programm abstürzte. Sie können jedes der oben genannten Tools verwenden, um es zu betrachten. Es kann sehr hilfreich sein, wenn Sie diese Art von Problemen diagnostizieren.

Abhängig davon, wie hart das Programm arbeitet, kann es ein einfacher Fall sein, bei dem die JVM nicht weiß, wann ein guter Zeitpunkt für die Garbage Collection ist. Sie können auch die Optionen für die parallele Garbage Collection prüfen.

12
mezmo

Ich stellte auch das gleiche Problem gegenüber. Ich löste, indem ich das Errichten durch die folgenden Schritte als durchführte.

-> Klicken Sie mit der rechten Maustaste auf das Projekt und wählen Sie Ausführen als -> Konfigurationen ausführen

Wählen Sie Ihr Projekt als BaseDirectory aus. Anstelle von Zielen geben Sie Eclipse: Eclipse installieren

-> Geben Sie in der zweiten Registerkarte -Xmx1024m als VM Argumente ein.

6
PSR

Ich möchte hinzufügen, dass dieses Problem häufig auftretenden Java Speicherverlusten ähnelt.

Wenn der JVM-Garbage-Collector den "Abfall" -Speicher Ihrer EE-Anwendung Java/Java im Laufe der Zeit nicht löschen kann, wird OutOfMemoryError: Java Heap Space das Ergebnis.

Es ist wichtig, zuerst eine ordnungsgemäße Diagnose durchzuführen:

  • Aktivieren Sie wörtlich: gc . Auf diese Weise können Sie das Muster des Speicherwachstums im Laufe der Zeit verstehen.
  • Generieren und analysieren Sie einen JVM-Heap-Dump . Auf diese Weise können Sie den Speicherbedarf Ihrer Anwendung ermitteln und die Ursache des Speicherverlusts (der Speicherverluste) ermitteln.
  • Sie können auch Java -Profiler und einen Laufzeit-Speicherleckanalysator wie Plumbr verwenden, um Sie bei dieser Aufgabe zu unterstützen.
3
P-H

Versuchen Sie, -Xmx für mehr Speicher hinzuzufügen (Java -Xmx1024M YourClass), und vergessen Sie nicht, nicht mehr auf Variablen zu verweisen, die Sie nicht mehr benötigen (Speicherlecks).

2
ivy

Behalten Sie Verweise auf Variablen bei, die Sie nicht mehr benötigen (z. B. Daten aus früheren Simulationen)? Wenn ja, liegt ein Speicherverlust vor. Sie müssen nur herausfinden, wo dies geschieht, und sicherstellen, dass Sie die Verweise auf die Variablen entfernen, wenn sie nicht mehr benötigt werden (dies würde automatisch passieren, wenn sie den Gültigkeitsbereich verlassen).

Wenn Sie tatsächlich alle Daten aus früheren Simulationen im Speicher benötigen, müssen Sie die Größe des Heapspeichers erhöhen oder Ihren Algorithmus ändern.

1
Mario Duarte

Java soll den Heap-Speicherplatz für Sie freigeben, wenn nicht mehr auf alle Objekte verwiesen wird. Im Allgemeinen wird es jedoch nicht an das Betriebssystem zurückgesendet, sondern der Speicher bleibt für die interne Wiederverwendung erhalten. Vielleicht überprüfen Sie, ob Sie Arrays haben, die nicht gelöscht werden oder so.

0
Triton Man

Nein. Der Haufen wird vom Müllsammler geräumt, wann immer es sich anfühlt. Sie können ihn zum Ausführen auffordern (mit System.gc()), die Ausführung ist jedoch nicht garantiert.

Erhöhen Sie zuerst den Speicher, indem Sie -Xmx256m

0
Bozho