web-dev-qa-db-fra.com

Java espace mémoire insuffisant)

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.

47
randomafk

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
36
Michael Hernandez

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 ArrayLists ou HashMaps 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.

19
unkx80

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.

12
mezmo

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.

6
PSR

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:

  • Activer verbose: gc . Cela vous permettra de comprendre l'évolution de la mémoire au fil du temps.
  • Générez et analysez un JVM Heap Dump . Cela vous permettra de comprendre l’empreinte mémoire de votre application et de localiser la source de la ou des fuites de mémoire.
  • Vous pouvez également utiliser les profileurs Java et l'analyseur de fuite de mémoire au moment de l'exécution, tels que Plumbr , pour vous aider dans cette tâche.
3
P-H

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).

2
ivy

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.

1
Mario Duarte

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.

0
Triton Man

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

0
Bozho