Je reçois l'erreur suivante lors de l'exécution d'un programme multi-threading
Java.lang.OutOfMemoryError: Java heap space
L'erreur ci-dessus s'est produite dans l'un des threads.
Jusqu'à ma connaissance, l'espace de segment de mémoire est occupé uniquement par des variables d'instance. Si cela est correct, alors pourquoi cette erreur s'est produite après avoir fonctionné correctement pendant que l'espace est alloué pour les variables d'instance lors de la création de l'objet.
Y at-il un moyen d'augmenter l'espace de tas?
Quels changements dois-je apporter à mon programme pour qu'il prenne moins de place?
Si vous souhaitez augmenter votre espace de mémoire, vous pouvez utiliser Java -Xms<initial heap size> -Xmx<maximum heap size>
sur la ligne de commande. Par défaut, les valeurs sont basées sur la version de JRE et la configuration du système. Vous pouvez trouver plus d'informations sur les options VM sur le site Web Java }.
Cependant, je vous recommanderais de profiler votre application pour savoir pourquoi votre taille de segment de mémoire est mangée. NetBeans a un très bon profileur inclus. Je crois qu’il utilise le jvisualvm
sous le capot. Avec un profileur, vous pouvez essayer de trouver où de nombreux objets sont créés, quand les objets sont ramassés, etc.
1.- Oui, mais cela renvoie assez à toute la mémoire utilisée par votre programme.
2.- Oui, voir les options Java VM
-Xms<size> set initial Java heap size
-Xmx<size> set maximum Java heap size
C'est à dire
Java -Xmx2g
attribuer un maximum de 2 Go de RAM à votre application
Mais vous devriez voir si vous n'avez pas de fuite de mémoire en premier.
3.- Cela dépend du programme. Essayez des fuites de mémoire ponctuelles. Cette question serait difficile à répondre. Dernièrement, vous pouvez profiler en utilisant JConsole pour essayer de savoir où va votre mémoire
Vous pouvez consulter ce site pour en savoir plus sur la mémoire dans la machine virtuelle Java: http://developer.streamezzo.com/content/learn/articles/optimization-heap-memory-usage
J'ai trouvé utile d'utiliser visualgc pour observer le remplissage des différentes parties du modèle de mémoire afin de déterminer les modifications à apporter.
Il est difficile de déterminer quelle partie de la mémoire a été remplie, d’où visualgc, car vous voudrez peut-être simplement changer la partie qui pose un problème plutôt que de simplement dire:
Bien! Je vais donner 1G de RAM à la JVM.
Essayez d’être plus précis sur ce que vous faites, à long terme, vous trouverez probablement le programme plus performant.
Pour déterminer où peut se trouver la fuite de mémoire, vous pouvez utiliser des tests unitaires à cet effet, en testant la quantité de mémoire utilisée avant et après le test, et si le changement est trop important, vous pouvez l'examiner, mais vous devez faites la vérification pendant que votre test est toujours en cours.
Pour augmenter la taille du tas, vous pouvez utiliser l'argument -Xmx lors du démarrage de Java. par exemple.
-Xmx256M
- Jusqu'à ma connaissance, l'espace de segment de mémoire est occupé uniquement par des variables d'instance. Si cela est correct, cette erreur s’est produite après une exécution correcte de temps en temps, l’espace alloué aux instances d’instance étant alloué au moment de la création de l’objet.
Cela signifie que vous créez de façon continue plus d'objets dans votre application. Les nouveaux objets seront stockés dans la mémoire de tas et c’est la raison de la croissance de la mémoire de tas.
Heap ne contient pas seulement des variables d'instance. Il stockera tous les types de données non primitifs (Objets). La durée de vie de ces objets peut être courte (bloc de méthode) ou longue (jusqu'à ce que l'objet soit référencé dans votre application).
- Y at-il un moyen d'augmenter l'espace de tas?
Oui. Jetez un oeil à cet Oracle article pour plus de détails.
Il existe deux paramètres pour définir la taille du tas:
-Xms:, qui définit la taille de tas initiale et minimale
-Xmx:, qui définit la taille de tas maximale
- Quels changements dois-je apporter à mon programme pour qu'il prenne moins de place?
Cela dépend de votre application.
Définissez la mémoire de tas maximale selon les exigences de votre application
Ne provoquez pas de fuites de mémoire dans votre application
Si vous trouvez des fuites de mémoire dans votre application, recherchez la cause première à l'aide d'outils de profilage tels que MAT , Visual VM , jconsole etc Une fois que vous avez trouvé la cause, corrigez les fuites.
Notes importantes d'Oracle article
Cause: Le message de détail Espace de segment de mémoire Java indique que l'objet n'a pas pu être alloué dans le segment de mémoire Java. Cette erreur n'implique pas nécessairement une fuite de mémoire.
Raisons possibles:
Sur une note différente, utilisez de meilleurs algorithmes de récupération de place (CMS ou G1GC)
Regardez cette question pour comprendre G1GC
Vous pouvez obtenir la taille de votre mémoire en dessous de programe.
public class GetHeapSize {
public static void main(String[] args) {
long heapsize = Runtime.getRuntime().totalMemory();
System.out.println("heapsize is :: " + heapsize);
}
}
en conséquence, vous pouvez également augmenter la taille du tas en utilisant: Java -Xmx2g http://www.Oracle.com/technetwork/Java/javase/tech/vmoptions-jsp-140102.html
Dans la plupart des cas, le code n'est pas optimisé. Libérez les objets dont vous pensez qu'ils ne seront plus nécessaires. Évitez de créer des objets dans votre boucle à chaque fois. Essayez d'utiliser des caches. Je ne sais pas comment se porte votre application. Mais en programmation, une règle de la vie normale s’applique aussi
Mieux vaut prévenir que guérir. "Ne créez pas d'objets inutiles"
Les variables locales sont situées sur la pile. L'espace de tas est occupé par des objets.
Vous pouvez utiliser l'option -Xmx
.
Fondamentalement, l'espace mémoire est utilisé chaque fois que vous allouez un nouvel objet avec new
et libéré un certain temps après que l'objet n'est plus référencé. Veillez donc à ne pas conserver de références à des objets dont vous n’avez plus besoin.
Non, je pense que vous pensez à la pile. L'espace de tas est occupé par des objets. La façon de l'augmenter est -Xmx256m, en remplaçant le 256 par le montant dont vous avez besoin sur la ligne de commande.
Pour éviter cette exception, si vous utilisez JUnit et Spring, ajoutez-le à chaque classe de test:
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
Dans Netbeans, allez dans la barre d’outils 'Exécuter', -> 'Définir la configuration du projet' -> 'Personnaliser' -> 'Exécuter' de sa fenêtre contextuelle -> 'Option de VM' -> Remplissez '-Xms2048m -Xmx2048m '. Cela pourrait résoudre le problème de la taille du tas.