motivo per cui il numero di thread Java cresce nel tempo


Ho un programma di console Java standalone che utilizza circa 80-170 (160 è un numero tipico a carico medio) thread in produzione. Alcuni codici vengono sostituiti nel progetto che è funzionalmente fine, ma il numero di thread cresce continuamente dopo l'avvio del programma. Ho riconosciuto il problema quando è quasi andato in crash la macchina virtuale. Quindi aveva 30.000 thread.

Mi piacerebbe trovare la ragione di questo comportamento nell'ambiente di produzione, quindi se c'è qualcosa di utile strumento deve essere un programma a riga di comando o dovrebbe essere in grado di eseguire da host remoto.

L'ho controllato con il comando 'ps huH p / wc-l' e il programma VisualVm.Sfortunatamente VisualVm remote fornisce informazioni solo sui numeri dei thread, la scheda "Thread" non è attiva

Ho cercato di ottenere informazioni utili dal comando jstack , ma non sono riuscito a trovare qual è il nuovo thread che ha creato ecc. da

"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)

O

"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)

Non capisco cosa sono.

Potresti aiutarmi come potrei scoprire quale codice crea nuovi thread ancora e ancora? Qualche buon strumento?

Grazie!

Author: Alexander, 2018-08-17

2 answers

Direi che jstack è uno strumento corretto per tale compito. Puoi capire la natura dei thread con le loro tracce di stack e il codice sorgente. Ad esempio at java.util.TimerThread.mainLoop(Timer.java:526) significa che il codice utilizza la classe Timer e il suo thread è in attesa della pianificazione successiva. java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074) significa che si utilizza una delle implementazioni ExecutorService e il suo thread di lavoro è in attesa dell'attività successiva. Prova ad analizzare quanti thread del pool di thread sono vivi e perché, probabilmente sono la fonte del tuo problema.

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

La vista monitor thread in JProfiler può mostrare la traccia dello stack in cui è stato creato qualsiasi thread finché è stata attiva la registrazione della CPU.

inserisci qui la descrizione dell'immagine

Disclaimer: La mia azienda sviluppa JProfiler.

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