Umgang mit “java.lang.OutOfMemoryError: Java-Heap-Space” -Fehler (64MB Heap-Größe)

Ich schreibe eine clientseitige Swing- Anwendung (graphical font designer) auf Java 5 . Kürzlich java.lang.OutOfMemoryError: Java heap space ich auf java.lang.OutOfMemoryError: Java heap space , weil ich bei der Speichernutzung nicht konservativ bin. Der Benutzer kann eine unbegrenzte Anzahl von Dateien öffnen und das Programm behält die geöffneten Objekte im Speicher. Nach einer kurzen Recherche fand ich Ergonomie in der 5.0 Java Virtual Machine und andere sagen auf Windows-Maschine, dass die JVM die maximale Heap-Größe als 64MB .

Wie sollte ich angesichts dieser Situation mit dieser Einschränkung umgehen?

Ich könnte die maximale Größe des Heapspeichers mit der Befehlszeilenoption Java erhöhen, aber dazu müsste man das verfügbare RAM ermitteln und ein Startprogramm oder Skript schreiben. Außerdem wird die Erhöhung auf ein endliches Maximum das Problem letztlich nicht lösen.

Ich könnte etwas von meinem Code schreiben, um Objekte im Dateisystem häufig zu persistieren (database ist die gleiche Sache), um den Speicher freizugeben. Es könnte funktionieren, aber es ist wahrscheinlich auch eine Menge Arbeit.

Wenn Sie mich auf Details der obigen Ideen oder einige Alternativen wie automatischen virtuellen Speicher hinweisen könnten , die Größe des Heapspeichers dynamisch erweitern , wird das großartig.

   

Letztendlich haben Sie immer ein endliches Maximum an Heap zu verwenden, egal auf welcher Plattform Sie laufen. In Windows 32 bit ist dies etwa 2 GB (nicht speziell Heap, sondern die Gesamtmenge an Speicher pro process). Es kommt einfach vor, dass Java den Standard verkleinert (vermutlich, damit der Programmierer keine Programme erstellen kann, die eine Speicherzuordnung haben, ohne auf dieses Problem einzugehen und genau zu untersuchen, was sie tun).

So gibt es mehrere Ansätze, die Sie verwenden können, um zu bestimmen, wie viel Speicher Sie benötigen, oder um die Menge an Speicher zu reduzieren, die Sie verwenden. Ein häufiger Fehler bei mit Garbage Collection erfassten Sprachen wie Java oder C # besteht darin, Verweise auf Objekte, die Sie nicht mehr verwenden, beizubehalten oder viele Objekte zuzuweisen, wenn Sie sie stattdessen wiederverwenden können. Solange Objekte einen Verweis auf sie haben, verwenden sie weiterhin Heap-Speicher, da der Garbage Collector sie nicht löscht.

In diesem Fall können Sie einen Java-Speicher-Profiler verwenden, um zu bestimmen, welche Methoden in Ihrem Programm eine große Anzahl von Objekten zuweisen, und dann feststellen, ob sichergestellt werden kann, dass sie nicht mehr referenziert werden oder nicht. Eine Option, die ich in der Vergangenheit verwendet habe, ist “JMP” http://www.khelekore.org/jmp/ .

Wenn Sie feststellen, dass Sie diese Objekte aus einem bestimmten Grund zuweisen und Referenzen beibehalten müssen (je nachdem, was Sie tun, ist dies möglicherweise der Fall), müssen Sie beim Starten des Programms nur die maximale Größe des Heapspeichers erhöhen. Sobald Sie jedoch das Speicherprofil erstellt haben und verstehen, wie Ihre Objekte zugewiesen werden, sollten Sie eine bessere Vorstellung davon haben, wie viel Speicher Sie benötigen.

Im Allgemeinen, wenn Sie nicht garantieren können, dass Ihr Programm in irgendeiner endlichen Menge von Speicher (vielleicht abhängig von der Eingabegröße) läuft, werden Sie immer auf dieses Problem stoßen. Erst nachdem Sie all dies ausgeschöpft haben, müssen Sie Objekte auf der Festplatte ausspeichern usw. An diesem Punkt sollten Sie einen guten Grund haben zu sagen: “Ich brauche Xgb Speicher” für etwas und Sie können nicht daran arbeiten, es zu verbessern Ihre Algorithmen oder Speicherzuweisungsmuster. Im Allgemeinen wird dies nur für Algorithmen der Fall sein, die mit großen Datensätzen arbeiten (wie eine database oder ein wissenschaftliches Analyseprogramm), und dann werden Techniken wie Caching und speicherprogrammierte IO nützlich.

Führen Sie Java mit der Befehlszeilenoption -Xmx , mit der die maximale Größe des -Xmx wird.

Siehe hier für Details. .

Sie können pro Projekt angeben, wie viel Heap-Speicherplatz Ihr Projekt benötigt

Folgendes ist für Eclipse Helios / Juno / Kepler :

Rechter Mausklick auf

  Run As - Run Configuration - Arguments - Vm Arguments, 

dann füge das hinzu

 -Xmx2048m 

Die Größe des Heapspeichers zu erhöhen ist kein “Fix”, sondern ein “Gips”, 100% temporär. Es wird wieder irgendwo anders abstürzen. Schreiben Sie Hochleistungscode, um diese Probleme zu vermeiden.

  1. Verwenden Sie möglichst lokale Variablen.
  2. Stellen Sie sicher, dass Sie das richtige Objekt ausgewählt haben (EX: Auswahl zwischen String, StringBuffer und StringBuilder)
  3. Verwenden Sie ein gutes Codesystem für Ihr Programm (EX: Verwenden von statischen Variablen VS nicht statischen Variablen)
  4. Andere Sachen, die an deinem Code funktionieren könnten.
  5. Versuchen Sie, sich mit MULTY GEWINDEN zu bewegen

Großer Vorbehalt —- In meinem Büro fanden wir heraus, dass wir (auf einigen Windows-Rechnern) nicht mehr als 512 m für den Java-Heap reservieren konnten. Dies ist auf das Kaspersky Anti-Virus-Produkt zurückzuführen, das auf einigen dieser Computer installiert ist. Nach der Deinstallation dieses AV-Produkts, haben wir festgestellt, dass wir mindestens 1,6 GB zuweisen können, dh -XMX1600m (m ist obligatorisch, andernfalls wird es zu einem anderen Fehler führen “Zu kleiner Anfangshaufen”).

Keine Ahnung, ob dies bei anderen AV-Produkten passiert, aber vermutlich geschieht dies, weil das AV-Programm in jedem Adressraum einen kleinen Speicherblock reserviert, wodurch eine einzelne wirklich große Zuweisung verhindert wird.

VM-Argument funktionierte für mich in Eclipse. Wenn Sie Eclipse Version 3.4 verwenden, gehen Sie folgendermaßen vor

Gehe zu Run --> Run Configurations --> wähle dann das Projekt unter maven build -> wähle dann den Tab “JRE” -> dann -Xmx1024m .

Alternativ dazu können Sie auch Run --> Run Configurations --> select the "JRE" tab --> Xmx1024m Run --> Run Configurations --> select the "JRE" tab --> dann – Xmx1024m

Dies sollte den Speicher-Heap für alle Builds / Projekte erhöhen. Die oben genannte Speichergröße beträgt 1 GB. Sie können Ihre Wünsche optimieren.

Ja, mit -Xmx können Sie mehr Speicher für Ihre JVM konfigurieren. Um sicher zu sein, dass Sie nicht auslaufen oder Speicher verschwenden. Machen Sie einen Heap-Dump und verwenden Sie den Eclipse Memory Analyzer , um Ihren Speicherverbrauch zu analysieren.

Ich möchte gerne Empfehlungen aus dem oracle- Trouble-Shooting- Artikel hinzufügen

Ausnahme im Thread thread_name: java.lang.OutOfMemoryError: Java- Heapspeicher

Die Detailnachricht Java-Heap-Speicher zeigt an, dass das Objekt im Java-Heapspeicher nicht zugeordnet werden konnte. Dieser Fehler bedeutet nicht unbedingt ein Speicherleck

Mögliche Ursachen:

  1. Einfaches Konfigurationsproblem , bei dem die angegebene Heap-Größe für die Anwendung nicht ausreicht.

  2. Anwendung hält unbeabsichtigt Verweise auf Objekte , und dies verhindert, dass die Objekte Müll gesammelt werden.

  3. Übermäßiger Einsatz von Finalizern .

Eine andere mögliche Quelle für diesen Fehler tritt bei Anwendungen auf, die Finalizer übermäßig verwenden. Wenn eine class über eine Finalize-Methode verfügt, wird bei der Garbage-Collection-Zeit für die Objekte dieses Typs kein Speicherplatz zurückgewonnen

Nach der Garbage-Collection werden die Objekte zur Finalisierung in die Warteschlange gestellt, was zu einem späteren Zeitpunkt erfolgt. Finalisten werden von einem Daemon-Thread ausgeführt, der die Finalisierungswarteschlange bedient. Wenn der Finalizer- Thread nicht mit der Finalisierungswarteschlange mithalten kann, könnte der Java- Heapspeicher gefüllt werden, und dieser Typ der OutOfMemoryError- Ausnahme würde ausgetriggers.

Ein Szenario, das diese Situation verursachen kann, ist, wenn eine Anwendung Threads mit hoher Priorität erstellt , die dazu führen, dass die Finalisierungswarteschlange mit einer Geschwindigkeit zunimmt, die schneller ist als die Rate, mit der der Finalizer-Thread diese Warteschlange bedient.

Befolgen Sie die folgenden Schritte:

  1. Öffnen Sie catalina.sh von Kater / Mülleimer.

  2. Chnage JAVA_OPTS zu

     JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms1536m -Xmx1536m -XX:NewSize=256m -XX:MaxNewSize=256m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+DisableExplicitGC" 
  3. Starten Sie Ihren Tomcat neu

Ich habe woanders gelesen, dass Sie versuchen können – java.lang.OutOfMemoryError zu fangen und auf dem catch-Block können Sie alle Ressourcen freigeben, von denen Sie wissen, dass sie viel Speicher benötigen, Verbindungen schließen usw., dann machen Sie eine System.gc () wiederhole es, was immer du tun wolltest.

Ein anderer Weg ist dies, obwohl ich nicht weiß, ob das funktionieren würde, aber ich teste gerade, ob es auf meiner Anwendung funktioniert.

Die Idee besteht darin, die Garbage Collection durch Aufruf von System.gc () auszuführen, von dem bekannt ist, dass es den freien Speicher erhöht. Sie können dies überprüfen, nachdem ein Memory-Gobbling-Code ausgeführt wurde.

 //Mimimum acceptable free memory you think your app needs long minRunningMemory = (1024*1024); Runtime runtime = Runtime.getRuntime(); if(runtime.freeMemory() 

Ich habe dasselbe Problem von Java-Heap-Größe konfrontiert. Ich habe zwei Lösungen, wenn Sie Java 5 (1.5) verwenden.

Erstens: -just install jdk1.6 und gehen Sie zu den Voreinstellungen von Eclipse und setzen Sie den jre Pfad von jav1 1.6, wie Sie installiert haben.

2.: – Überprüfen Sie Ihr VM Argument und lassen Sie es, was auch immer es ist. Füge einfach eine Zeile unter allen Argumenten hinzu, die in VM-Argumenten als -Xms512m -Xmx512m -XX: MaxPermSize = … m (192m) enthalten sind.

Ich denke, es wird funktionieren …

Eine einfache Möglichkeit, OutOfMemoryError in Java zu lösen, besteht darin, die maximale Größe des OutOfMemoryError zu erhöhen, indem Sie die JVM-Optionen -Xmx512M wird Ihr OutOfMemoryError sofort getriggers. Dies ist meine bevorzugte Lösung, wenn ich OutOfMemoryError in Eclipse, Maven oder ANT bekomme, während ich ein Projekt erstelle, weil es auf der Grundlage der Größe des Projekts leicht möglich ist, den Speicher zu leeren.

Hier ist ein Beispiel für die Erhöhung der maximalen Heap-Größe von JVM. Außerdem ist es besser, -Xmx auf -Xms zu belassen, entweder 1: 1 oder 1: 1,5, wenn Sie die Heap-Größe in Ihrer Java-Anwendung festlegen.

export JVM_ARGS="-Xms1024m -Xmx1024m"

Referenzlink

Wenn Sie die Speicherbelegung zur Laufzeit überwachen müssen, bietet das Paket java.lang.management MBeans, mit denen Sie die Speicherpools in Ihrer VM überwachen können (z. B. eden space, Tenure Generation usw.) und auch das Garbage-Collection-Verhalten.

Der freie Heapspeicher, der von diesen MBeans gemeldet wird, hängt stark vom GC-Verhalten ab, insbesondere dann, wenn Ihre Anwendung viele Objekte generiert, die später als GC-Ed-Objekte bezeichnet werden. Ein möglicher Ansatz besteht darin, den freien Heap-Speicher nach jedem vollständigen GC zu überwachen, mit dem Sie möglicherweise eine Entscheidung treffen können, wie Sie Speicher freigeben, indem Sie Objekte persistieren.

Letztendlich ist es am besten, die Speichererhaltung so weit wie möglich zu begrenzen, solange die performance akzeptabel ist. Wie ein vorheriger Kommentar angemerkt hat, ist die Speicherkapazität immer begrenzt, aber deine App sollte eine Strategie haben, um mit der Speichererschöpfung umzugehen.

Beachten Sie, dass Sie Java WebStart (mit einer “ondisk” -Version, nicht der Netzwerkversion – in Java 6u10 und höher) verwenden sollten, wenn Sie dies in einer Implementierungssituation benötigen, da Sie die verschiedenen Argumente für die JVM in einem Kreuz angeben können Plattform Weg.

Andernfalls benötigen Sie einen betriebssystemspezifischen Launcher, der die benötigten Argumente festlegt.

Standardmäßig verwendet JVM für die Entwicklung kleine und kleine Konfigurationen für andere leistungsbezogene functionen. Aber für die Produktion kann man zB (zusätzlich kann Application Server spezifische Konfiguration existieren) -> (Wenn immer noch nicht genug Speicher zur Verfügung steht um die Anforderung zu erfüllen und der Heap bereits die maximale Größe erreicht hat, wird ein OutOfMemoryError auftreten)

 -Xms set initial Java heap size -Xmx set maximum Java heap size -Xss set java thread stack size -XX:ParallelGCThreads=8 -XX:+CMSClassUnloadingEnabled -XX:InitiatingHeapOccupancyPercent=70 -XX:+UnlockDiagnosticVMOptions -XX:+UseConcMarkSweepGC -Xms512m -Xmx8192m -XX:MaxPermSize=256m (in java 8 optional) 

Zum Beispiel: Unter Linux Platform für den Produktionsmodus bevorzugte Einstellungen.

Nach dem Herunterladen und Konfigurieren des Servers auf diese Weise http://www.ehowstuff.com/how-to-install-and-setup-apache-tomcat-8-on-centos-7-1-rhel-7/

1. Erstellen Sie die Datei setenv.sh im Ordner / opt / tomcat / bin /

  touch /opt/tomcat/bin/setenv.sh 

2. Öffnen und schreiben Sie diese Parameter, um den bevorzugten Modus einzustellen.

 nano /opt/tomcat/bin/setenv.sh export CATALINA_OPTS="$CATALINA_OPTS -XX:ParallelGCThreads=8" export CATALINA_OPTS="$CATALINA_OPTS -XX:+CMSClassUnloadingEnabled" export CATALINA_OPTS="$CATALINA_OPTS -XX:InitiatingHeapOccupancyPercent=70" export CATALINA_OPTS="$CATALINA_OPTS -XX:+UnlockDiagnosticVMOptions" export CATALINA_OPTS="$CATALINA_OPTS -XX:+UseConcMarkSweepGC" export CATALINA_OPTS="$CATALINA_OPTS -Xms512m" export CATALINA_OPTS="$CATALINA_OPTS -Xmx8192m" export CATALINA_OPTS="$CATALINA_OPTS -XX:MaxMetaspaceSize=256M" 

3. service tomcat restart

Beachten Sie, dass die JVM mehr Speicher als nur den Heap verwendet. Zum Beispiel werden Java-Methoden, Thread-Stacks und native Handles im Speicher getrennt vom Heap sowie interne JVM-Datenstrukturen zugewiesen.

Wenn Sie weiterhin Referenzen auf Objekte zuweisen und behalten, füllen Sie jede Menge Speicher aus, die Sie haben.

Eine Option besteht darin, eine transparente Datei zu schließen und zu öffnen, wenn sie Tabs wechseln (Sie behalten nur einen pointers auf die Datei, und wenn der Benutzer die Registerkarte wechselt, schließen und bereinigen Sie alle Objekte … es wird die Datei langsamer verändern … aber …) und vielleicht nur 3 oder 4 Dateien im Speicher behalten.

Eine andere Sache, die Sie tun sollten, ist, wenn der Benutzer eine Datei öffnet, lädt und alle OutOfMemoryError abfängt, dann (da es nicht möglich ist, die Datei zu öffnen) diese Datei schließen, ihre Objekte säubern und den Benutzer warnen, dass er unbenutzt schließen soll Dateien.

Ihre Idee, den virtuellen Speicher dynamisch zu erweitern, triggers das Problem nicht, da die Maschine auf Ressourcen beschränkt ist. Sie sollten also vorsichtig sein und Speicherprobleme behandeln (oder zumindest vorsichtig mit ihnen sein).

Ein paar Hinweise, die ich bei Speicherlecks gesehen habe, sind:

-> Beachte, dass wenn du etwas in eine Sammlung legst und es danach vergisst, du immer noch einen starken Bezug darauf hast, also annulliere die Sammlung, reinige sie oder tu etwas damit … wenn nicht, wirst du eine finden Speicherleck schwer zu finden.

-> Vielleicht kann die Verwendung von Sammlungen mit schwachen Referenzen (weakhashmap …) bei Speicherproblemen helfen, aber Sie müssen vorsichtig damit sein, denn Sie könnten feststellen, dass das Objekt, nach dem Sie suchen, gesammelt wurde.

-> Eine andere Idee, die ich gefunden habe, ist eine persistente Sammlung zu entwickeln, die auf databaseobjekten gespeichert ist, die am wenigsten benutzt und transparent geladen sind. Dies wäre wahrscheinlich der beste Ansatz …

In Bezug auf Netbeans könnten Sie maximale Heap-Größe festlegen, um das Problem zu lösen. Erstens, gehen Sie zu ‘Ausführen’, dann -> ‘Set Project Configuration’ -> ‘Anpassen’ -> ‘run’ von seinem Pop-up-Fenster -> ‘VM Option’ -> füllen ‘-Xms2048m – Xmx2048m ‘.

Wenn dieses Problem in Wildfly 8 und JDK1.8 auftritt, müssen Sie MaxMetaSpace-Einstellungen anstelle von PermGen-Einstellungen angeben.

Zum Beispiel müssen wir die Konfiguration in der Datei setenv.sh von wildfly hinzufügen. JAVA_OPTS="$JAVA_OPTS -XX:MaxMetaspaceSize=256M"

Weitere Informationen finden Sie unter Wildfly Heap Issue