Domanda

Mi chiedo se sia possibile avere un controllo sulle istanze in esecuzione di una determinata classe. Il problema particolare che ha innescato questo è stato un'applicazione che non si chiude bene a causa di una serie di thread in esecuzione.

Sì, lo so che puoi demonizzare i thead e questi non reggeranno l'uscita dell'applicazione. Ma mi è venuto da chiedermi se questo fosse possibile. La cosa più vicina che posso è i classloader (protetti!) findLoadedClass , anche se per farlo dovresti eseguire il tuo classloader.

In una nota correlata, è così che gli strumenti di profilazione riescono a tenere traccia degli handle degli oggetti? eseguendo i propri classloader personalizzati? o c'è un bel modo complicato che non vedo?

È stato utile?

Soluzione

Puoi effettivamente ottenere una traccia dello stack di tutti i thread in esecuzione scaricati nello stdout usando kill -QUIT <pid> su un * NIX come OS, oppure eseguendo l'applicazione in una console di Windows e premendo Ctrl-Pause (come osserva un altro poster. )

Tuttavia, sembra che tu stia chiedendo modi programmatici per farlo. Quindi, supponendo che ciò che vuoi davvero sia l'insieme di tutti i thread che le pile di chiamate correnti includono uno o più metodi di una determinata classe ...

La cosa migliore che posso trovare che non coinvolge le chiamate in JVMTI è ispezionare le pile di tutti i thread in esecuzione. Non l'ho provato, ma dovrebbe funzionare in Java 1.5 e versioni successive. Tieni presente che questo, per definizione, non è TUTTO sicuro per i thread (l'elenco dei thread in esecuzione - e le loro tracce di stack correnti - cambieranno costantemente sotto di te ... sarebbe necessario un sacco di cose paranoiche per fare effettivamente uso di questo elenco.)

public Set<Thread> findThreadsRunningClass(Class classToFindRunning) {

  Set<Thread> runningThreads = new HashSet<Thread>();
  String className = classToFindRunning.getName();

  Map<Thread,StackTraceElement[]> stackTraces = Thread.getAllStackTraces();
  for(Thread t : stackTraces.keySey()) {
    StackTraceElement[] steArray = stackTraces.get(t);
    for(int i = 0;i<steArray.size();i++) {
      StackTraceElement ste = steArray[i];
      if(ste.getClassName().equals(className)) {
        runningThreads.add(t);
        continue;
      }
    }
  }

  return runningThreads;
}

Fammi sapere se questo approccio funziona per te!

Altri suggerimenti

Da questa pagina ,

  

Un profiler Java utilizza un'interfaccia nativa per JVM (JVMPI per Java < = 1.4.2 o JVMTI per Java > = 1.5.0 ) per ottenere informazioni di profilazione da un'applicazione Java in esecuzione.

Ciò equivale ad alcuni Codice nativo fornito da Sun che dà un profiler agganciato alla JVM.

Se hai solo bisogno di una rapida traccia dello stack della tua applicazione in esecuzione per scoprire quali thread stanno bloccando l'uscita JVM, puoi inviargli il segnale QUIT.

$ kill -QUIT <pid of java process>

In Windows è necessario eseguire l'applicazione in una finestra della console (usando java.exe, non javaw.exe), quindi è possibile premere Ctrl-Pausa per generare il dump dello stack. In entrambi i casi & # 8217; s scritto su stdout.

Uso Visual VM per monitorare la JVM. Ha molte funzionalità, provalo.

Penso che tu abbia bisogno di un dump del thread Java . Questo dovrebbe elencare tutti i thread con quello che stanno facendo al momento. Anch'io ho avuto un problema simile, che un dump di thread ha aiutato a risolvere (thread di Quartz Scheduler, che non sono usciti al termine di Tomcat).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top