10
votes

Comment détecter la cause de OutofMemoryError?

J'ai une plainte qu'une application de serveur de la mienne se bloque sur une charge élevée.
C'est une application Web exécutée dans tomcat 5 code>.
Je vois les décharges de threads et je vois qu'il y a une erreur extraordinaire

1 Tisiginfo Dump Event "Systhrow" (00040000) Détail de
"Java / Lang / OutofMemoryloryError" "Échec de la création de thread: Retval -1073741830, Errno 12"> reçu 1tidateTime Date: 2012/07/17 à 20:03:17 1 Nom> Javacore FileName: C: \ ServerApplication \ Tomcat5 \ bin \ javacore.34545719.4646464.4172.0003.txt p> blockQquote>

Les informations sur le tas sont les suivantes: p>

1STHEAPFREE    Bytes of Heap Space Free: 2D19F3C0   
1STHEAPALLOC   Bytes of Heap Space Allocated: 5DC00000


4 commentaires

"" Java / Lang / OutofMemoryError "" Échec de la création de thread: Retval -1073741830, errno 12 ">" Cette section est incroyablement importante, l'appel à la bibliothèque Windows a échoué, vous devez aller chercher ces codes dans une référence Microsoft ( MSDN, etc.) et voyez ce qu'ils veulent dire.


@ user439407: merci! Vous parlez-vous au retval ou errno que vous recommandez que je devrais rechercher? Où devrais-je regarder?


Les deux, mais Erno serait probablement plus informatif (RETVAL indique probablement simplement une échec, peut-être quel type d'échec, pas sûr, je n'ai aucune expérience avec Windows)


Bien que pas nécessairement une réponse à votre question, avez-vous essayé d'utiliser les connecteurs NIO ou APR à Tomcat au lieu de la valeur par défaut? De cette façon, vous ne serez pas reproduire un nouveau fil par connexion.


5 Réponses :


5
votes

Je sais ce que vous voulez dire, cela peut être déroutant de trouver quelque part pour commencer.

regarder analyseur de mémoire Eclipse (tapis). Il utilisera JHAT pour vider un instantané de mémoire de votre programme dans un fichier, que vous pouvez ré-ouvrir et analysera.

Le navigateur pour ce fichier décrit tous les objets créés par le programme très soigneusement et vous pouvez examiner différents niveaux pour trouver si quelque chose est suspect.


Ajoutez mes commentaires pour répondre ...

Droite lorsque votre fichier WebApp WebApp, videz-le au tapis. Mat vous dira quel objet est créé un tas de fois. Si c'est un objet personnalisé, et cela est souvent, il est facile de trouver. Sinon, vous pouvez voir son parent, l'amputer et dribbler de là (désolé pour l'exemple graphique, je ne suis pas entièrement centré sur le moment :).

Oh, et j'ai oublié de mentionner, vous pouvez exécuter le programme plusieurs fois dans plusieurs conditions et faire une décharge à chaque fois. Ensuite, vous pouvez analyser chaque décharge pour la tendance.


Mais dans mon cas, que dois-je utiliser? J'ai une application Web en cours d'exécution à Tomcat

Désolé, j'ai raté cela aussi. Si je ne me trompe pas, le tapis vide le processus JVM , afin que la machine virtuelle est exécutée sur votre boîte, vous pouvez jeter son processus et voir ce qui se passe.


un autre commentaire muté dans une solution partielle ...

Cela devient de plus en plus difficile que ce n'est en réalité. Sérieusement, c'est assez facile, après avoir exécuté le tapis une ou deux fois pour avoir la suspension des choses. Exécutez votre application jusqu'à ce que la chose se bloque. Jette le. Change quelque chose. Courir, crash, décharge. Répéter. Ensuite, ouvrez les décharges dans le tapis et comparez ce qui semble suspect.

La partie la plus difficile quand j'apprendais ceci trouvait le ID de processus à vider - ce qui n'est toujours pas trop engourdissant.


8 commentaires

Ok.Je peux essayer cela aussi. Mais j'utilise déjà un outil d'analyse et les données de la OP sont en réalité des données que l'outil m'a aidé à trouver. Je ne suis tout simplement pas sûr de les utiliser pour trouver la cause fondamentale


Je vois que JMAP attend un exécutable pour mapper les segments de mémoire.Mais dans mon cas, que dois-je utiliser? J'ai une application Web en cours d'exécution à Tomcat.


Fait des commentaires mais ils sont mieux ajoutés à la réponse.


Le problème est que je ne peux pas reproduire cela ici. Vous dites que je devrais reproduire cela, puis vous connecter au processus pour collecter les décharges?


Ces problèmes ne peuvent donc être résolus que de manière dynamique? En reproduisant l'erreur? On ne peut pas trouver le problème "statiquement" en regardant dans les journaux?


Longue histoire courte, oui. Mon expérience personnelle m'a amené à croire que les erreurs doivent être reproduites afin de déboguer, sauf si vous êtes un super-héros de variété rare.


OK.Manks.Mais est là une sorte d'information que je peux extraire du fait que 45% des threads attendent et 50% sont garés? Comment cela peut-il conduire à un ex-memororyError s'il y a un tas de tas gratuitement?


Pas de soucis, bonne chance. Cela pénètre dans une autre question ... Le commentaire UI ici est de devoir tellement de choses que je dois le couper court. Cela ressemble à un bon candidat pour une nouvelle question. C'est un très gros sujet, de toute façon. :)



7
votes

Vous devez démarrer la JVM avec le -xx: + tasdumponOutofMemorylorororror drapeau. Cela produira un dépotoir de tas lorsque le OutofMemoryError est généré.

Ensuite, comme @steve a dit, vous pouvez utiliser un outil tel que le tapis pour analyser le décharge et voir quels objets sont alloués et qui en gardent des références. Cela vous donnera généralement des informations sur la raison pour laquelle votre JVM est épuisant sa mémoire.


0 commentaires

9
votes

Selon Ce message :

Il y a deux causes possibles du Java.Lang.outofMemororyError: Impossible de créer un message de thread:

  • Il y a trop de threads en cours d'exécution et le système est à court de ressources internes pour créer de nouveaux threads.
  • Le système est à court de mémoire natale à utiliser pour le nouveau fil. Les threads nécessitent une mémoire natale pour les structures JVM internes, une Java ™ pile et une pile indigène.

    Donc, cette erreur peut bien être complètement indépendante à la mémoire, juste que trop de threads sont créés ...

    EDIT:

    Comme vous avez 695 threads, vous auriez besoin de 695 fois la taille de la pile comme mémoire. Considérant Cet article sur les limites de thread, je soupçonne que vous essayez de créer trop de threads pour l'espace mémoire virtuel disponible.


0 commentaires

2
votes

Un message similaire sur IBM WebSphere montre ceci ligne

"Échec de la création d'un thread: retval"

Comme indiquant l'OOM NATIVE , ce qui signifie que certains threads (du processus) tentent de demander une grande partie de la mémoire sur le tas.

Le lien IBM ci-dessus a une série d'étapes - dont certaines sont spécifiques à IBM. Jeter un coup d'oeil.

à partir d'une perspective d'utilisation de la mémoire native:

  • Paramètres de tas Java maximum
  • Pilote JDBC
  • Code JNI ou Bibliothèques autochtones
  • Collection des ordures de cours inutilisés. ENSURETHAT -XNOCLASSGC n'est pas défini.
  • Paramètres de la piscine de thread (piscines de fil de taille fixe)
  • trop de chargeurs de classe, etc., mais ceux-ci ne sont pas très courants.
  • Nombre de classes / chargeurs de classes de Javacores.

    Une autre chose que vous pourriez regarder est le Permgensepace - quelle est la taille?

    Ce lien http://www.codingthearchitecture.com/2008/01/ 14 / jvm_lies_the_outofmemory_myth.html suggère

    L'augmentation de l'allocation du tas exacerbe réellement ce problème! Ce diminue la hauteur marine le compilateur et d'autres composants natifs, ont jouer avec. Donc, la solution à mon problème était la suivante: 1.Réveloppez le tas alloué à la JVM. 2. Retirez les fuites de mémoire causées par des objets natifs ne sont pas libérées en temps opportun.

    Avez-vous également configuré une valeur dans Server.xml pour Maxthreads? La valeur par défaut est 200 mais votre application semble avoir 695?


2 commentaires

Oui, j'utilise un pool de 500 threads in server.xml. Ce numéro est-il trop grand?


Vous pouvez essayer de réduire - lorsque vous autorisez 500 threads de demande entrant dans le système, chacun aura besoin de son propre gestionnaire de fichiers, etc. qui prend la mémoire. Cela dit - le non. des threads de demande est différent des threads d'application 695 dans le processus - la réponse de Beny23 est meilleure



0
votes

0 commentaires