Il y a un jour, après quelques mois de fonctionnement normal, notre application Java se bloque de temps en temps avec l'erreur suivante:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (safepoint.cpp:247), pid=2075, tid=140042095163136
# guarantee(PageArmed == 0) failed: invariant
#
# JRE version: 6.0_23-b05
# Java VM: Java HotSpot(TM) 64-Bit Server VM (19.0-b09 mixed mode linux-AMD64 compressed oops)
# An error report file with more information is saved as:
# /var/chat/jSocketer/build/hs_err_pid2075.log
#
# If you would like to submit a bug report, please visit:
# http://Java.Sun.com/webapps/bugreport/crash.jsp
#
J'ai regardé dans hs_err_pid2075.log et vu qu'il y avait un thread actif, qui traitait une communication réseau. Cependant, aucune modification de l'application ou de l'environnement n'a été apportée au cours des derniers mois. De plus, il n'y a pas eu de croissance de charge. Que puis-je faire pour comprendre, quelle est la raison d'un crash? Existe-t-il des étapes communes pour enquêter sur un plantage JVM?
Le crash est dans la JVM, pas dans le code natif externe. Cependant, l'opération sur laquelle il s'est écrasé a été lancée par une DLL externe.
Cette ligne du fichier hs_err_pid explique l’opération qui a échoué:
VM_Operation (0x00007f5e16e35450): GetAllStackTraces, mode: safepoint, requested by thread 0x0000000040796000
Maintenant, le thread 0x0000000040796000 est
0x0000000040796000 JavaThread "YJPAgent-Telemetry" daemon [_thread_blocked, id=2115, stack(0x00007f5e16d36000,0x00007f5e16e37000)]
qui est un fil créé par Yourkit. "GetAllStackTraces" est quelque chose qu'un profileur doit appeler pour pouvoir échantillonner. Si vous supprimez le profileur, le crash ne se produira pas.
Avec ces informations, il est impossible d'indiquer la cause du blocage, mais vous pouvez procéder comme suit: Supprimez tous les paramètres -XX VM, -verbose: gc et les paramètres de débogage VM. Ils pourraient interférer avec l'interface de profilage de la machine virtuelle Java.
Mettre à jour
Le code qui appelle Java.lang.Thread#getAllStackTraces()
ou Java.lang.Thread#getStackTrace()
peut déclencher le même blocage
Les deux fois où j'ai été témoin de crashs JVM répétés étaient tous deux dus à une panne matérielle, à savoir la mémoire vive. Exécuter un utilitaire memtest est la première chose que je voudrais essayer.
D'après le rapport d'erreur, je vois que le YourKit agent est chargé. Son fil de télémétrie est mentionné en tant que demandeur de l'opération qui semble échouer. Essayez d'exécuter l'application sans l'agent YJP pour voir si vous pouvez toujours reproduire le blocage.
En règle générale, les accidents de la machine virtuelle Java sont assez difficiles à diagnostiquer. Cela pourrait arriver à cause d'un bogue dans un code JNI ou dans le JRE lui-même. Si vous suspectez ce dernier problème, il peut être intéressant de soumettre un rapport de bogue à Oracle.
Quoi qu'il en soit, je vous recommande de mettre à niveau vers la dernière version de Java 6 pour vous assurer qu'il ne s'agit pas d'un problème connu qui a déjà été résolu. Au moment de la rédaction de ce document, la version actuelle est Java 6 update 29.
Si vous ne vous mêlez pas de ce qui pourrait causer cela directement (ce qui signifie essentiellement utiliser du code natif ou des bibliothèques appelant du code natif), il s'agit presque toujours d'un bogue de la machine virtuelle ou du problème matériel.
Si cela fonctionne bien depuis des lustres et a maintenant commencé à tomber en panne, il me semble que le problème matériel est le plus probable. Pouvez-vous l'exécuter sur une autre machine pour éliminer le problème? Bien sûr, la mise à niveau vers la dernière mise à jour Java ne ferait certainement pas de mal.
Passer à une autre version de linux-kernel "corrige" le problème d’écrasement de la machine virtuelle Java ( http://forum.proxmox.com/threads/6998-Best-strategy-to-handle-strange-JVM-errors-inside-VPS? p = 40286 # post40286 ). Cela m'a aidé avec mon vrai serveur. Le système d'exploitation Ubuntu 10.04 LTS était installé sur le serveur avec la version 2.6.32-33 du noyau. Donc, la mise à jour du noyau a résolu ce problème. JVM n'a plus de crash.