J'ai une application Java (basée sur le Web) qui affiche parfois une utilisation du processeur très élevée (presque 90%) pendant plusieurs heures. La commande Linux TOP
montre ceci. Au redémarrage de l'application, le problème disparaît.
Donc pour enquêter:
Je prends Thread Dump pour trouver ce que font les threads. Plusieurs threads se trouvent dans l'état 'RUNNABLE'
, certains dans quelques autres états. En prenant des décharges de threads répétées, je vois des threads qui sont toujours présents dans l'état 'RUNNABLE'
. Donc, ils semblent être le coupable.
Mais je ne suis pas en mesure de dire avec certitude quel thread accapare le processeur ou s’est engagé dans une boucle infinie (ce qui entraîne une utilisation élevée du processeur).
Les journaux ne sont pas nécessairement utiles, car le code incriminé peut ne rien enregistrer.
Comment puis-je rechercher - Quelle partie de l'application ou quel thread est à l'origine de l'utilisation élevée du processeur? - D'autres idées?
Si un profileur n'est pas applicable dans votre configuration, vous pouvez essayer d'identifier le thread en suivant les étapes dans this post .
Fondamentalement, il y a trois étapes:
top -H
et obtenez le PID du thread avec le processeur le plus élevé.Vous pouvez être victime d'un problème de récupération de place.
Lorsque votre application nécessite de la mémoire et que sa configuration est insuffisante pour être utilisée, le collecteur de mémoire fonctionnera souvent, ce qui consommera beaucoup de cycles de la CPU . et encore . Lorsque vous redéployez votre application, la mémoire est effacée et la récupération de place ne se produira pas plus que nécessaire, de sorte que l'utilisation du processeur reste faible jusqu'à ce qu'elle soit à nouveau pleine.
Vous devez vérifier qu'il n'y a pas de fuite de mémoire possible dans votre application et qu'elle est bien configurée pour la mémoire (vérifiez le paramètre -Xmx
, voir Que signifie l'option Java -Xmx?? )
En outre, qu'utilisez-vous comme cadre Web? JSF s'appuie beaucoup sur les sessions et consomme beaucoup de mémoire. Pensez au mieux à être sans état!
Quelle est la charge de l'utilisateur pendant ces périodes de pointe du processeur? Vous dites qu'il s'agit d'une application Web, les problèmes d'utilisation de la mémoire sont donc à l'origine de vos préoccupations. Si vous stockez beaucoup d'éléments dans la session, par exemple, et que le nombre de sessions est suffisamment élevé, le serveur d'applications va commencer à se débattre. C'est également un cas où le GC pourrait aggraver la situation, selon le schéma que vous utilisez. Plus d'informations sur l'application et la configuration du serveur seraient utiles pour indiquer plus d'idées de débogage.
Dans le thread dump, vous pouvez trouver le numéro de ligne ci-dessous.
pour le thread principal en cours d'exécution ...
"main" #1 prio=5 os_prio=0 tid=0x0000000002120800 nid=0x13f4 runnable [0x0000000001d9f000]
Java.lang.Thread.State: **RUNNABLE**
at Java.io.FileOutputStream.writeBytes(Native Method)
at Java.io.FileOutputStream.write(FileOutputStream.Java:313)
at com.rana.samples.**HighCPUUtilization.main(HighCPUUtilization.Java:17)**
Votre première approche devrait être de trouver toutes les références à Thread.sleep et de vérifier que:
Dormir est la bonne chose à faire - vous devriez utiliser une sorte de mécanisme d'attente si possible - peut-être que l'utilisation prudente d'une BlockingQueue
pourrait aider.
Si dormir est la bonne chose à faire, dormez-vous suffisamment longtemps - il est souvent très difficile de répondre à cette question.
L'erreur la plus courante dans la conception multithread est de croire que tout ce que vous devez faire pour attendre que quelque chose se produise est de le vérifier et de dormir un instant dans une boucle serrée. C'est rarement une solution efficace - vous devriez toujours essayer de wait
pour l'événement.
Le deuxième problème le plus courant est de boucler sans dormir. C'est encore pire et c'est un peu moins facile à localiser.