[JAVA] [JVM] Contestons la réponse à l'échec du MOO (mémoire insuffisante)

introduction

Les connaissances de base de JVM ont été présentées dans cet article. [JVM] MOO (mémoire insuffisante) Connaissances nécessaires pour le dépannage

J'aborderai désormais des solutions spécifiques de MOO.

Production

À partir de là, lorsque vous rencontrez un problème MOO, vous apprendrez les actions pour le résoudre. Ici, nous présenterons également des outils utilisables concrètement. (Reportez-vous au lien pour savoir comment l'utiliser.)

Événements détaillés du problème abordés cette fois

Pour résumer les problèmes survenus cette fois, C'était un événement que le processus java s'arrêtait une fois par semaine. Lorsque j'ai vérifié le taux d'utilisation de la mémoire avec la commande sar, il a été utilisé jusqu'à environ 100% juste avant de tomber. Le journal des incidents JVM contenait le mot OOM.

Ce qui suit est un résumé de la politique d'enquête, de la méthode d'enquête, des points à noter, etc. Lorsque j'enquêtais, je ne savais pas comment enquêter et j'ai raté des informations importantes. J'interprétais étrangement des données incorrectes.

Donc, la méthode d'enquête de lance décrite ici est la meilleure méthode à laquelle je puisse penser pour le moment.

Politique d'enquête

Vous voudrez peut-être enquêter dans l'ordre suivant.

  1. Vérifiez hs_err_ .log pour isoler le problème (cela peut être considérablement réduit)
  2. Vérifiez l'état du tas dans le journal gc
  3. S'il y a un problème avec le tas Java, identifiez le problème à partir du vidage du tas
  4. S'il y a un problème avec le non-tas, identifiez le problème à partir du nombre de threads
  5. Suspectez OOM Killer si l'utilisation de la mémoire augmente pour des raisons autres que celles ci-dessus

** La première chose à faire est que lorsque vous traitez des problèmes MOO, les problèmes sont entrelacés de manière non linéaire. Il est nécessaire d'avoir une mentalité d'acier qui formule calmement des hypothèses et les vérifie régulièrement. ** **

1. Vérifiez hs_err_ .log pour isoler le problème (cela peut être considérablement réduit)

** En consultant ce journal, vous pouvez réduire considérablement le problème du MOO. ** ** En répétant la vérification d'hypothèse par la suite, je pense que la vitesse pour atteindre la cause sera beaucoup plus rapide. Veuillez vérifier avec le plus grand soin. (Je me battais sans le savoir au début)

À propos, ce journal est le journal qui est généré lorsque la machine virtuelle Java plante. Si vous ne définissez rien dans les options de démarrage de la JVM, il sera affiché dans le répertoire actuel. Si vous souhaitez spécifier la destination de sortie, vous pouvez décider en définissant les options de démarrage suivantes.

java -XX:ErrorFile=/var/log/java/java_error%p.log

Lire hs_err_ .log

Lisez maintenant hs_err_ .log pour identifier le problème. Lorsque vous ouvrez le contenu du fichier journal, vous trouverez la description suivante. ** Veuillez vous référer à la description car elle peut réduire le problème dans une certaine mesure. ** **

-Il y a un problème avec le tas Java

Exception in thread "main": java.lang.OutOfMemoryError: Java heap space

Java heap space indicates that an object could not be allocated in the Java heap une. Je n'ai pas pu allouer un objet à la zone de tas Java! Peut être interprété comme Autrement dit, la capacité de la zone de tas Java est petite. → Augmenter la capacité résoudra le problème.

the message might be an indication that the application is unintentionally holding references to objects Il y a aussi. Un objet a été référencé en permanence et manque progressivement de mémoire sans être soumis à la suppression du GC! Peut être interprété comme Donc c'est une fuite de mémoire → Le problème est résolu en effectuant un vidage de tas, en identifiant les objets qui augmentent progressivement et en collectant la source. Voir ** 3. S'il y a un problème avec le tas Java, identifiez le problème à partir du vidage du tas ** ci-dessous

-Il y a un problème avec le tas permanent

Exception in thread "main": java.lang.OutOfMemoryError: PermGen space

PermGen space indicates that the permanent generation is full. une. Il n'y a pas assez de zone permanente! Peut être interprété comme En d'autres termes, il est nécessaire de sécuriser une zone suffisante avec l'option -XX: MaxPermSize.

De plus, les variables statiques et la classe chargée en premier dans le chargeur de classe sont stockées dans cette zone.

-Il y a un problème avec le tas Java.

Exception in thread "main": java.lang.OutOfMemoryError: Requested array size exceeds VM limit

Requested array size exceeds VM limit indicates that the application (or APIs used by that application) attempted to allocate an array that is larger than the heap size. une. Le tableau n'a pas pu être alloué dans la zone de tas Java! Peut être interprété comme Autrement dit, la capacité de la zone de tas Java est petite. → Augmenter la capacité résoudra le problème. Sinon, le problème peut être résolu en effectuant un vidage de tas, en identifiant les objets qui augmentent progressivement et en récupérant la source. Voir ** 3. S'il y a un problème avec le tas Java, identifiez le problème à partir du vidage du tas ** ci-dessous

-Il y a un problème avec le tas C

Exception in thread "main": java.lang.OutOfMemoryError: request <size> bytes for <reason>. Out of swap space?

the HotSpot VM code reports this apparent exception when an allocation from the native heap failed and the native heap might be close to exhaustion. une. La mémoire n'a pas été allouée au tas natif (tas C)! Peut être interprété comme Au fait, c'est ce problème que j'ai traité. Lorsque vous rencontrez ce problème, vous pouvez supposer que la cause est le nombre de threads. Donc ** 4. Si vous rencontrez un problème avec le non-tas, voir ** Identifier le problème à partir du nombre de threads **

Pour plus de détails, consultez le site suivant.

Je pense que les informations fournies jusqu'à présent ont réduit le problème dans une certaine mesure. De là, le problème se transforme d'hypothèse en fait.

2. Vérifiez l'état du tas dans le journal gc

Comme mentionné dans la section d'entrée, en définissant -verbose: gc comme option de démarrage, Vous pouvez obtenir le journal gc. Si vous regardez ce journal, vous pouvez voir comment la zone de tas fluctue à la suite de l'exécution de GC mineurs et majeurs. ** GC Viewer ** est très utile pour la visualisation et la visualisation.

Cet article est utile pour savoir comment utiliser et afficher l'outil https://qiita.com/i_matsui/items/aabbdaa169c6ae51ecb3

3. S'il y a un problème avec le tas Java, identifiez le problème à partir du vidage du tas

En visualisant et en comparant les résultats des vidages de tas à l'aide de Memory Analyzer Vous verrez s'il y a vraiment un problème avec le tas Java. Les articles suivants sont très utiles pour savoir comment utiliser Memory Analyzer.

La méthode spécifique est -Obtenir un vidage de tas. (Décrit dans la section d'entrée)

Une fois que vous savez quel objet est le problème, modifiez la source. Cependant, si la zone de tas est insuffisante, vous pouvez l'augmenter.

4. S'il y a un problème avec le non-tas, identifiez le problème à partir du nombre de threads

En comparant les vidages de threads, le nombre de threads peut être comparé.

#confirmation pid
jcmd -l

#Obtenir un vidage de thread
jstack <pid> > threaddump.txt

De plus, en utilisant jconsole, vous pouvez visualiser la transition du nombre de threads, donc Vous pouvez voir si le nombre de threads augmente proportionnellement au temps.

Je ne l'ai pas utilisé, mais je vais le présenter car il semble très utile. https://github.com/irockel/tda

Vous pouvez connaître le nombre de threads et l'utilisation de la mémoire avec la commande suivante, afin de pouvoir comparer si elle augmente avec le temps.

ps auxww -L | grep -e java -e PID | grep -v grep

J'ai fait référence à cet article. http://d.hatena.ne.jp/rx7/20101219/p1

Demande: Je pense qu'il existe d'autres moyens plus efficaces S'il vous plaît laissez-moi savoir si vous savez.

5. Suspectez OOM Killer si l'utilisation de la mémoire augmente pour des raisons autres que celles ci-dessus

Spécifications Linux ~ cache ~

L'une des idées de Linux est un mécanisme pour utiliser activement la mémoire libre. L'ennui de ceci n'est pas visible avec la commande ps. Par exemple, si vous regardez l'utilisation de la mémoire d'un processus avec ps aux, le processus java utilise 30% de mémoire. Cependant, quand on regarde le taux d'utilisation de la mémoire entière avec sar -r 1, il est d'environ 90%.

Si cela se produit, il est probable qu'il soit utilisé pour la mise en cache. À propos, environ 60% de la mémoire était également utilisée pour le cache de page à mon époque.

#Effacer tout le cache de page
# echo 1 > /proc/sys/vm/drop_caches

Vous pouvez supprimer le cache de page par la méthode ci-dessus, mais elle est subtile car elle supprime également le cache nécessaire. Au pire, une exécution régulière avec cron résout le problème de la mémoire utilisée pour le cache de page.

Bien sûr, vous devez également rechercher la cause de la mise en cache des pages. Vous pouvez soupçonner qu'une grande quantité de journaux est en cours de sortie (des E / S se produisent).

Les articles suivants seront utiles https://tech.mercari.com/entry/2015/07/16/170310

Spécifications Linux ~ OOM Killer ~

alors. Un meurtrier se cache sous Linux. Afin d'éviter la panique lorsque Linux manque de mémoire Il existe une spécification pour tuer de force un processus qui utilise de la mémoire.

Lorsqu'un processus est tué par le tueur OOM, le processus qui a été tué est affiché dans le fichier suivant.

less /var/log/messages

02:53:58 xxxxx1 kernel: Out of memory: Killed process 28036, UID 80, (xmllint).

De plus, le journal qui apparaît lorsque la JVM plante, le pid de hs_err_ .log, Si le pid tué correspond à / var / log / messages, vous savez qu'il a été tué par OOM Killer.

Les articles suivants seront utiles. https://blog.ybbo.net/2013/07/10/oom-killer%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/

Points à prendre en compte lors de l'enquête

-S'il y a une différence environnementale entre l'environnement local et l'environnement de vérification, il peut ne pas être possible de reproduire. Changements de comportement en fonction du système d'exploitation tel que Linux (Parce qu'il peut y avoir un problème autre que le processus java)

-Faites attention au timing lors de l'acquisition d'un vidage de tas pour le traitement par lots. Par exemple, si vous effectuez un vidage de tas d'un processus java qui s'exécute régulièrement lorsque la charge est élevée, Bien sûr, il y a trop d'objets pour bien comparer. Par conséquent, lors de la comparaison, vous devez obtenir un vidage de tas dans les mêmes conditions et conditions et comparer.

・ Ne pas mener d'enquêtes sans hypothèses ou politiques Je pense que c'est la chose la plus importante. Au cours de mes recherches, je recherche différents endroits qui m'intéressent et je regarde des graphiques. Cela n'a presque aucun sens, vous devriez donc vous arrêter. Je le fais parfois.

Résumé

Nous avons résumé comment identifier des problèmes spécifiques lorsque des problèmes de MOO surviennent et comment les résoudre. J'espère que cela aide les gens qui souffrent de problèmes de MOO comme moi.

De plus, puisque je viens de résumer ce que j'ai étudié, des méthodes autres que celles présentées ici, Je pense qu'il y a plus de perspectives. Si vous le savez, faites-le moi savoir.

Recommended Posts

[JVM] Contestons la réponse à l'échec du MOO (mémoire insuffisante)
Cloud 9 est à court de mémoire: mémorandum du tutoriel Rails