Mon application consomme actuellement pas mal de mémoire car elle exécute des simulations physiques. Le problème est que, lors de la 51e simulation, Java émettra généralement une erreur en raison d’un espace de mémoire insuffisante (mon programme exécute finalement des milliers de simulations).
Y a-t-il quoi qu'il en soit que je ne puisse pas simplement augmenter l'espace du tas, mais modifier mon programme afin que l'espace du tas soit effacé après chaque exécution afin que je puisse exécuter un nombre arbitraire de simulations?
Merci
-modifier-
Merci les gars. Il s'avère que le logiciel de simulation n'a pas effacé les informations après chaque analyse et que ces analyses ont toutes été stockées dans une liste.
Il n'est pas possible d'augmenter dynamiquement le segment de mémoire de manière dynamique, car celui-ci est alloué lorsque la machine virtuelle Java est démarrée.
Cependant, vous pouvez utiliser cette commande
Java -Xmx1024M YourClass
mettre la mémoire à 1024
ou, vous pouvez définir un min max
Java -Xms256m -Xmx1024m YourClassNameHere
Si vous utilisez beaucoup de mémoire et que vous faites face à des fuites de mémoire, vous voudrez peut-être vérifier si vous utilisez un grand nombre de ArrayList
s ou HashMap
s avec chacun de nombreux éléments.
Un ArrayList
est implémenté en tant que tableau dynamique . Le code source de Sun/Oracle montre que, lorsqu'un nouvel élément est inséré dans un ArrayList
complet, un nouveau tableau de 1,5 fois la taille du tableau d'origine est créé et les éléments copiés. Cela signifie que vous pourriez perdre jusqu'à 50% de l'espace disponible dans chaque ArrayList
que vous utilisez, sauf si vous appelez sa méthode trimToSize
. Ou mieux encore, si vous connaissez le nombre d'éléments que vous allez insérer auparavant, appelez le constructeur avec la capacité initiale comme argument.
Je n'ai pas examiné le code source de HashMap
très attentivement, mais à première vue, il apparaît que la longueur du tableau dans chaque HashMap
doit être une puissance de deux, ce qui en fait une autre implémentation d'une dynamique tableau. Notez que HashSet
est essentiellement un wrapper autour de HashMap
.
Vous pouvez utiliser divers outils pour diagnostiquer ce problème. Le JDK inclut JVisualVM qui vous permettra de vous connecter à votre processus en cours d'exécution et d'afficher les objets susceptibles de devenir hors de contrôle. Netbeans est entouré d'un wrapper qui fonctionne assez bien. Eclipse est doté de l’analyseur de mémoire Eclipse, celui que j’utilise le plus souvent. Il semble tout simplement mieux gérer les gros fichiers de vidage. Il existe également une option de ligne de commande, - XX: + HeapDumpOnOutOfMemoryError qui vous donnera un fichier qui est essentiellement un instantané de la mémoire de votre processus lorsque votre programme est tombé en panne. Vous pouvez utiliser n'importe lequel des outils mentionnés ci-dessus pour l'examiner, cela peut vraiment beaucoup aider à diagnostiquer ce type de problèmes.
En fonction de la difficulté du programme, il se peut qu’un simple cas de machine virtuelle ne sachant pas le bon moment pour la récupération de place, vous pouvez également consulter les options de récupération de place parallèles.
J'ai également fait face au même problème. J'ai résolu en construisant en suivant les étapes.
-> Faites un clic droit sur le projet sélectionnez RunAs -> Run configurations
Sélectionnez votre projet en tant que BaseDirectory. Au lieu de buts, donnez Eclipse: eclipse install
-> Dans le deuxième onglet, indiquez -Xmx1024m sous la forme VM arguments.
Je voudrais ajouter que ce problème est similaire aux fuites de mémoire courantes Java.
Lorsque le récupérateur de mémoire JVM ne parvient pas à effacer la mémoire "résiduelle" de votre application Java/Java EE, OutOfMemoryError: Java heap espace sera le résultat.
Il est important d’effectuer d’abord un diagnostic correct:
Essayez d’ajouter -Xmx pour plus de mémoire (Java -Xmx1024M YourClass
), et n'oubliez pas de cesser de référencer les variables dont vous n’avez plus besoin (fuites de mémoire).
Conservez-vous des références aux variables dont vous n’avez plus besoin (par exemple, les données des simulations précédentes)? Si c'est le cas, vous avez une fuite de mémoire. Vous devez simplement trouver où cela se produit et vous assurer que vous supprimez les références aux variables lorsqu'elles ne sont plus nécessaires (ceci se produirait automatiquement si elles sortaient du champ d'application).
Si vous avez réellement besoin de toutes les données des simulations précédentes en mémoire, vous devez augmenter la taille du tas ou modifier votre algorithme.
Java est supposé effacer l'espace de mémoire pour vous lorsque tous les objets ne sont plus référencés. Il ne le restera généralement pas dans le système d'exploitation, mais conservera cette mémoire pour sa propre réutilisation interne. Peut-être vérifier pour voir si vous avez des tableaux qui ne sont pas effacés ou quelque chose.
Non. Le tas est effacé par le ramasse-miettes chaque fois que vous en avez envie. Vous pouvez lui demander de s'exécuter (avec System.gc()
), mais son exécution n'est pas garantie.
Essayez d’augmenter la mémoire en mettant -Xmx256m