Comment faire face à " java.lang.Erreur "OutOfMemoryError: Espace de tas Java" (taille de tas de 64 Mo)


Je suis en train d'écrire un côté client Swing application graphique (concepteur de la police) sur Java 5. Récemment, je rencontre une erreur java.lang.OutOfMemoryError: Java heap space car je ne suis pas conservateur sur l'utilisation de la mémoire. L'utilisateur peut ouvrir un nombre illimité de fichiers et le programme conserve les objets ouverts dans la mémoire. Après une recherche rapide, j'ai trouvéErgonomie dans la machine virtuelle Java 5.0 et d'autres disant sur la machine Windows, la taille maximale du tas par défaut de la JVM est 64MB.

Étant donné cela situation, comment dois-je faire face à cette contrainte?

Je pourrais augmenter la taille maximale du tas en utilisant l'optionligne de commande vers java, mais cela nécessiterait de déterminer la RAM disponible et d'écrire un programme ou un script de lancement. En outre, augmenter à un certain maximum fini ne résout finalement pas le problème.

Je pourrais réécrire une partie de mon code pour que les objets persistent fréquemment dans le système de fichiers (l'utilisation de la base de données est la même chose) pour libérer de la mémoire. Il pourrait fonctionner, mais il est probablement beaucoup de travail aussi.

Si vous pouviez me pointer vers les détails des idées ci-dessus ou certaines alternatives comme mémoire virtuelle automatique, étendant dynamiquement la taille du tas, ce sera génial.

Author: Bhaskara Arani, 2008-09-01

18 answers

En fin de compte, vous avez toujours un maximum fini de tas à utiliser, quelle que soit la plate-forme sur laquelle vous utilisez. Dans Windows 32 bits, cela représente environ 2 Go (pas spécifiquement le tas mais la quantité totale de mémoire par processus). Il arrive juste que Java choisisse de réduire la valeur par défaut (probablement pour que le programmeur ne puisse pas créer de programmes qui ont une allocation de mémoire fugace sans rencontrer ce problème et avoir à examiner exactement ce qu'ils font).

Donc cela étant donné qu'il y a plusieurs approches que vous pouvez prendre soit de déterminer la quantité de mémoire dont vous avez besoin, ou pour réduire la quantité de mémoire que vous utilisez. Une erreur courante avec les langages collectés par les ordures tels que Java ou C# est de conserver les références aux objets que vous n'utilisez plus, ou d'allouer de nombreux objets lorsque vous pouvez les réutiliser à la place. Tant que les objets ont une référence à eux, ils continueront à utiliser l'espace tas car le garbage collector ne les supprimera pas.

Dans ce cas, vous pouvez utiliser un Java memory profiler pour déterminer quelles méthodes de votre programme allouent un grand nombre d'objets, puis déterminer s'il existe un moyen de s'assurer qu'ils ne sont plus référencés ou de ne pas les allouer en premier lieu. Une option que j'ai utilisée dans le passé est " JMP " http://www.khelekore.org/jmp/.

Si vous déterminez que vous allouez ces objets pour une raison et que vous devez conserver les références (selon ce que vous faites, cela peut être le cas), vous vous aurez juste besoin d'augmenter la taille maximale du tas lorsque vous démarrez le programme. Cependant, une fois que vous avez effectué le profilage de la mémoire et compris comment vos objets sont alloués, vous devriez avoir une meilleure idée de la quantité de mémoire dont vous avez besoin.

En général, si vous ne pouvez pas garantir que votre programme fonctionnera dans une quantité finie de mémoire (peut-être en fonction de la taille de l'entrée), vous rencontrerez toujours ce problème. Ce n'est qu'après avoir épuisé tout cela que vous devrez examiner la mise en cache des objets sur le disque etc. À ce stade, vous devriez avoir une très bonne raison de dire "J'ai besoin de Xgb de mémoire" pour quelque chose et vous ne pouvez pas le contourner en améliorant vos algorithmes ou vos modèles d'allocation de mémoire. Généralement, cela ne sera généralement le cas que pour les algorithmes fonctionnant sur de grands ensembles de données (comme une base de données ou un programme d'analyse scientifique), puis des techniques telles que la mise en cache et les E / S mappées en mémoire deviennent utiles.

 196
Author: Ben Childs, 2017-06-02 21:52:52

Exécutez Java avec l'option de ligne de commande -Xmx, qui définit la taille maximale du tas.

Voir ici pour plus de détails..

 101
Author: Dave Webb, 2013-07-11 08:42:08

Vous pouvez spécifier par projet combien d'espace de tas votre projet veut

Ce qui suit est pour Eclipse Helios / Juno / Kepler :

Clic droit sur

 Run As - Run Configuration - Arguments - Vm Arguments, 

Puis ajoutez ceci

-Xmx2048m
 77
Author: allenhwkim, 2016-03-08 08:02:54

Augmenter la taille du tas n'est pas un "correctif" c'est un "plâtre", 100% temporaire. Il va se planter à nouveau dans un autre endroit. Pour éviter ces problèmes, écrivez du code haute performance.

  1. Utilisez des variables locales dans la mesure du possible.
  2. Assurez-vous de sélectionner l'objet correct (EX: Sélection entre String, StringBuffer et StringBuilder)
  3. Utilisez un bon système de code pour votre programme (EX: Utilisation de variables statiques VS variables non statiques)
  4. Autres choses qui pourraient fonctionner sur votre code.
  5. Essayez de vous déplacer avec le filetage multy
 30
Author: Yohan Weerasinghe, 2017-06-02 21:58:26

Grosse mise en garde ---- à mon bureau, nous trouvions que (sur certaines machines Windows) nous ne pouvions pas allouer plus de 512m pour le tas Java. Cela s'est avéré être dû au produit Kaspersky anti-virus installé sur certaines de ces machines. Après avoir désinstallé ce produit AV, nous avons constaté que nous pouvions allouer au moins 1,6 Go, c'est-à-dire-Xmx1600m (m est obligatoire autrement cela conduira à une autre erreur "Trop petit tas initial") fonctionne.

Aucune idée si cela se produit avec d'autres produits AV mais vraisemblablement cela se produit parce que le programme AV réserve un petit bloc de mémoire dans chaque espace d'adressage, empêchant ainsi une seule allocation vraiment importante.

 28
Author: David, 2017-07-06 13:35:43

L'argument VM a fonctionné pour moi dans eclipse. Si vous utilisez eclipse version 3.4, procédez comme suit

Aller Run --> Run Configurations -->, puis sélectionnez le projet maven build --> puis sélectionnez l'onglet "JRE" --> puis saisissez -Xmx1024m.

Alternativement, vous pouvez faire Run --> Run Configurations --> select the "JRE" tab --> puis entrer - Xmx1024m

Cela devrait augmenter le tas de mémoire pour tous les builds/projets. La taille de mémoire ci-dessus est de 1 Go. Vous pouvez optimiser comme vous le souhaitez.

 18
Author: loveall, 2015-01-12 14:50:54

Oui, avec-Xmx, vous pouvez configurer plus de mémoire pour votre JVM. Pour être sûr que vous ne fuyez pas ou ne gaspillez pas de mémoire. Prenez un vidage de tas et utilisez l'analyseur de mémoire Eclipse pour analyser votre consommation de mémoire.

 15
Author: kohlerm, 2008-10-09 08:22:25

Je voudrais ajouter des recommandations à partir d'oracle dépannage article

Exception dans thread thread_name: java.lang.Vous avez besoin d'un espace de mémoire Java.]}

Le message de détail Java heap space indique que l'objet n'a pas pu être alloué dans le tas Java. Cette erreur n'implique pas nécessairement une fuite de mémoire

causes Possibles:

  1. Problème de configuration simple, où la taille de tas spécifiée est insuffisant pour l'application.

  2. L'application contient involontairement des références à des objets, ce qui empêche les objets d'être collectés.

  3. Utilisation excessive de finaliseurs.

Une autre source potentielle de cette erreur se pose avec les applications qui font un usage excessif des finaliseurs. Si une classe a une méthode finalize, les objets de ce type n'ont pas leur espace récupéré à garbage temps de collecte

Après garbage collection, les objets sont mis en file d'attente pour finalisation, qui se produit ultérieurement. les finaliseurs sont exécutés par un thread de démon qui dessert la file d'attente de finalisation. Si le thread finalizer ne peut pas suivre la file d'attente de finalisation, alors le tas Java pourrait se remplir et ce type d'exception OutOfMemoryError serait levé.

Un scénario qui peut provoquer cette situation est quand un l'application crée des threads hautement prioritaires qui provoquent l'augmentation de la file d'attente de finalisation à un taux plus rapide que le taux auquel le thread finaliseur gère cette file d'attente.

 8
Author: Ravindra babu, 2017-06-29 15:35:27

Suivez les étapes ci-dessous:

  1. Ouvrir catalina.sh de tomcat / bin.

  2. Chnage JAVA_OPTE à

    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. Redémarrez votre serveur tomcat

 7
Author: Pradip Bhatt, 2017-07-03 17:59:03

J'ai lu ailleurs que vous pouvez essayer - catch java.lang.OutOfMemoryError et sur le bloc catch, vous pouvez libérer toutes les ressources que vous savez susceptibles d'utiliser beaucoup de mémoire, fermer les connexions, etc., puis faire un système.gc () puis réessayez ce que vous alliez faire.

Une autre façon est bien que, je ne sais pas si cela fonctionnerait, mais je teste actuellement si cela fonctionnera sur mon application.

L'idée est de faire la récupération de place en appelant le système.gc() qui est connu pour augmenter la quantité de mémoire libre. Vous pouvez continuer à vérifier cela après l'exécution d'un code engloutissant la mémoire.

//Mimimum acceptable free memory you think your app needs
long minRunningMemory = (1024*1024);

Runtime runtime = Runtime.getRuntime();

if(runtime.freeMemory()<minRunningMemory)
 System.gc();
 6
Author: mwangi, 2010-08-17 08:19:44

J'ai rencontré le même problème de taille de tas java. J'ai deux solutions si vous utilisez java 5 (1.5).

1er:-installez simplement jdk1.6 et accédez aux préférences d'eclipse et définissez le chemin jre de jav1 1.6 tel que vous l'avez installé.

2nd:-Vérifiez votre argument VM et laissez-le être quel qu'il soit. ajoutez simplement une ligne ci-dessous de tous les arguments présents dans les arguments VM comme -Xms512m - Xmx512m-XX: MaxPermSize=...m(192 m).

Je pense que cela fonctionnera...

 6
Author: Soumya Sandeep Mohanty, 2011-05-10 18:48:49

Un moyen facile de résoudre OutOfMemoryError en java est d'augmenter la taille maximale du tas en utilisant les options JVM -Xmx512M, cela résoudra immédiatement votre OutOfMemoryError. C'est ma solution préférée lorsque je sors OutOfMemoryError dans Eclipse, Maven ou ANT lors de la construction d'un projet, car en fonction de la taille du projet, vous pouvez facilement manquer de mémoire.

Voici un exemple d'augmentation de la taille maximale du tas de JVM, il est également préférable de conserver la ration-Xmx à-Xms soit 1:1 ou 1:1.5 si vous définissez la taille du tas dans votre application java.

export JVM_ARGS="-Xms1024m -Xmx1024m"

Lien De Référence

 6
Author: chaukssey, 2012-06-20 10:34:39

Si vous devez surveiller votre utilisation de la mémoire lors de l'exécution, le java.lang.le package de gestion offre des MBeans qui peuvent être utilisés pour surveiller les pools de mémoire de votre machine virtuelle (par exemple, eden space, génération tenured, etc.), ainsi que le comportement de récupération de place.

L'espace de tas libre rapporté par ces MBeans varie considérablement en fonction du comportement du GC, en particulier si votre application génère beaucoup d'objets qui sont plus tard GC-ed. Une approche possible consiste à surveiller l'espace de tas libre après chaque full-GC, que vous pourrez peut-être utiliser pour prendre une décision sur la libération de mémoire par des objets persistants.

En fin de compte, votre meilleur pari est de limiter votre rétention de mémoire autant que possible tandis que les performances restent acceptables. Comme un commentaire précédent l'a noté, la mémoire est toujours limitée, mais votre application devrait avoir une stratégie pour faire face à l'épuisement de la mémoire.

 5
Author: Leigh, 2008-10-09 12:04:30

Notez que si vous en avez besoin dans une situation de déploiement, envisagez d'utiliser Java WebStart (avec une version "ondisk", pas celle du réseau - possible dans Java 6u10 et versions ultérieures) car elle vous permet de spécifier les différents arguments à la JVM de manière multiplateforme.

Sinon, vous aurez besoin d'un lanceur spécifique au système d'exploitation qui définit les arguments dont vous avez besoin.

 3
Author: Thorbjørn Ravn Andersen, 2009-05-19 04:45:22

Par défaut pour le développement, la JVM utilise une petite taille et une petite configuration pour d'autres fonctionnalités liées aux performances. Mais pour la production, vous pouvez régler par exemple (En plus, une configuration spécifique au serveur d'applications peut exister) - >(S'il n'y a toujours pas assez de mémoire pour satisfaire la demande et que le tas a déjà atteint la taille maximale, une OutOfMemoryError se produira)

-Xms<size>        set initial Java heap size
-Xmx<size>        set maximum Java heap size
-Xss<size>        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)

Par exemple: Sur la plate-forme linux pour le mode de production paramètres préférables.

Après le téléchargement et la configuration serveur avec cette façon http://www.ehowstuff.com/how-to-install-and-setup-apache-tomcat-8-on-centos-7-1-rhel-7/

1.créer setenv.sh fichier sur le dossier / opt / tomcat / bin /

   touch /opt/tomcat/bin/setenv.sh

2.Ouvrez et écrivez ces paramètres pour définir le mode préférable.

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

Notez que la JVM utilise plus de mémoire que le tas. Exemple Les méthodes Java, les piles de threads et les poignées natives sont allouées en mémoire séparé du tas, ainsi que JVM interne structures de données.

 3
Author: Musa, 2018-03-03 12:32:02

Si vous continuez à allouer et à conserver des références à l'objet, vous remplirez n'importe quelle quantité de mémoire dont vous disposez.

Une option consiste à fermer et ouvrir un fichier transparent lorsqu'ils changent d'onglet (vous ne gardez qu'un pointeur sur le fichier, et lorsque l'utilisateur change d'onglet, vous fermez et nettoyez tous les objets... ça va ralentir le changement de fichier... mais...), et peut-être ne garder que 3 ou 4 fichiers en mémoire.

Une autre chose que vous devez faire est, lorsque l'utilisateur ouvre un fichier, le charge et intercepte tout OutOfMemoryError, puis (car il n'est pas possible d'ouvrir le fichier) fermez ce fichier, nettoyez ses objets et avertissez l'utilisateur qu'il doit fermer les fichiers inutilisés.

Votre idée d'étendre dynamiquement la mémoire virtuelle ne résout pas le problème, car la machine est limitée en ressources, vous devez donc être prudent et gérer les problèmes de mémoire (ou du moins, être prudent avec eux).

Quelques indices que j'ai vus avec des fuites de mémoire sont:

--> Conserver à l'esprit que si vous mettez quelque chose dans une collection et après, oubliez-le, vous avez toujours une référence forte, alors annulez la collection, nettoyez-la ou faites quelque chose avec... si pas, vous trouverez une fuite de mémoire difficile à trouver.

> > Peut-être, en utilisant des collections avec des références faibles (weakhashmap...) peut aider avec les problèmes de mémoire, mais vous devez en faire attention, car vous pourriez constater que l'objet que vous recherchez a été collecté.

> > Une autre idée que j'ai trouvée est de développer une collection persistante qui stocké sur les objets de base de données les moins utilisés et chargés de manière transparente. Ce serait probablement la meilleure approche...

 0
Author: SoulWanderer, 2010-09-29 07:47:13

En ce qui concerne netbeans, vous pouvez définir la taille maximale du tas pour résoudre le problème. Tout d'abord, allez dans 'Exécuter', puis- > 'Définir la configuration du projet'- > 'Personnaliser' - > 'exécuter' de sa fenêtre apparue - > 'Option VM' - > remplissez '- Xms2048m-Xmx2048m'.

 0
Author: Xiaogang, 2017-06-12 22:56:06

Si ce problème se produit dans Wildfly 8 et JDK1.8,nous devons spécifier les paramètres MaxMetaSpace au lieu des paramètres PermGen.

Par exemple, nous devons ajouter la configuration ci-dessous dans setenv.sh fichier de wildfly. JAVA_OPTS="$JAVA_OPTS -XX:MaxMetaspaceSize=256M"

Pour plus d'informations, veuillez vérifier Problème de tas Wildfly

 0
Author: satish, 2017-08-28 05:10:30