raison pour laquelle le nombre de threads Java augmente dans le temps


J'ai un programme de console Java autonome qui utilise environ 80-170 threads (160 est un nombre typique à charge moyenne) en production. Certains codes sont remplacés dans le projet, ce qui est fonctionnellement correct, mais le nombre de threads augmente continuellement après le démarrage du programme. J'ai reconnu le problème quand il est presque écrasé la machine virtuelle. Ensuite, il y avait 30.000 threads.

Je voudrais trouver la raison de ce comportement dans l'environnement de production, donc s'il y en a un utile outil il doit s'agir d'un programme en ligne de commande ou devrait pouvoir s'exécuter à partir d'un hôte distant.

Je l'ai vérifié avec la commande 'ps huH p | wc-l' et le programme VisualVM.Malheureusement, VisualVM remote ne donnant que des informations sur les numéros de thread, l'onglet" Thread " n'est pas actif

J'ai essayé d'obtenir des informations utiles de la commande jstack , mais je n'ai pas pu trouver quel est le nouveau thread qui a créé etc. à partir de

"Timer-459" #1864 daemon prio=10 os_prio=0 tid=0x0bb6c400 nid=0x3c4f in Object.wait() [0x2a980000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Object.java:502)
    at java.util.TimerThread.mainLoop(Timer.java:526)
    - locked <0x4d18bc80> (a java.util.TaskQueue)
    at java.util.TimerThread.run(Timer.java:505)

Ou

"pool-133-thread-2" #1877 prio=5 os_prio=0 tid=0x42a2c400 nid=0x3e5e waiting on condition [0x2b118000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x4d18ae80> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
    at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

Je ne comprends pas ce que sont-ils.

Pourriez-vous m'aider comment puis-je savoir quel code crée de nouveaux threads encore et encore? Tout bon outil?

Merci!

Author: Alexander, 2018-08-17

2 answers

, je dirais que jstack est un outil approprié pour une telle tâche. Vous pouvez comprendre la nature des threads par leurs traces de pile et leur code source. Par exemple, at java.util.TimerThread.mainLoop(Timer.java:526) signifie que votre code utilise la classe Timer et que son thread attend le prochain calendrier. java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074) signifie que vous utilisez l'une des implémentations ExecutorService et que son thread de travail attend la tâche suivante. Essayez d'analyser combien de threads de pool de threads sont vivants et pourquoi, ils sont probablement la source de votre problème.

 0
Author: Nikita Gorbachevski, 2018-08-17 15:04:20

La vue thread monitor dans JProfiler peut vous montrer la trace de pile à laquelle tout thread a été créé tant que l'enregistrement CPU était actif.

entrez la description de l'image ici

Avertissement: Mon entreprise développe JProfiler.

 1
Author: Ingo Kegel, 2018-08-17 17:37:02