在正在运行的JVM中查找正在运行的实例

时间:2023-01-18 18:32:07

I'm wondering if it's possible to get a handle on running instances of a given class. The particular issue that triggered this was an application that doesn't exit nicely because of a number of running threads.

我想知道是否可以获得运行给定类的实例的句柄。触发此问题的特定问题是由于许多正在运行的线程而无法正常退出的应用程序。

Yes, I know you can daemonize the theads, and they won't then hold up the application exit. But it did get me to wondering if this was possible. The closest thing I can is the classloaders (protected!) findLoadedClass, although you'd have to run through your own classloader to do this.

是的,我知道你可以守护theads,然后他们不会阻止应用程序退出。但它确实让我想知道这是否可行。我最接近的是classloaders(protected!)findLoadedClass,尽管你必须通过自己的类加载器来执行此操作。

On a related note, is this how profiling tools manage to track object handles? by running through their own custom classloaders? or is there some nice tricky way that I'm not seeing?

在相关的说明中,这是分析工具如何管理跟踪对象句柄?通过运行自己的自定义类加载器?还是有一些我看不到的好看的狡猾方式?

5 个解决方案

#1


You can indeed get a stack trace of all running Threads dumped to the stdout by using kill -QUIT <pid> on a *NIX like OS, or by running the application in a Windows console and pressing Ctrl-Pause (as another poster notes.)

您确实可以通过在类似操作系统的* NIX上使用kill -QUIT ,或者通过在Windows控制台中运行应用程序并按Ctrl-Pause(另一张海报备注)来获取转储到stdout的所有正在运行的线程的堆栈跟踪。 )

However, it seems like you're asking for programmatic ways to do it. So, assuming what you really want is the set of all Threads who's current call stacks include one or more methods from a given class...

但是,您似乎要求以编程方式执行此操作。因此,假设您真正想要的是当前调用堆栈的所有线程的集合包括来自给定类的一个或多个方法...

The best thing I can find that doesn't involve calls into the JVMTI is to inspect the stacks of all running threads. I haven't tried this, but it should work in Java 1.5 and later. Keep in mind that this is, by definition, not AT ALL thread-safe (the list of running threads - and their current stack traces - are going to constantly change underneath you...lots of paranoid stuff would be necessary to actually make use of this list.)

我能找到的最好的事情是不涉及对JVMTI的调用是检查所有正在运行的线程的堆栈。我没有试过这个,但它应该在Java 1.5及更高版本中运行。请记住,根据定义,这不是所有线程安全的(正在运行的线程列表 - 以及它们当前的堆栈跟踪 - 将在您下面不断变化...实际使用时需要大量偏执的东西这个清单。)

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;
}

Let me know if this approach works out for you!

如果这种方法适合你,请告诉我!

#2


From this page,

从这个页面,

A Java profiler uses a native interface to the JVM (the JVMPI for Java <=1.4.2 or the JVMTI for Java >=1.5.0) to get profiling information from a running Java application.

Java探查器使用JVM的本机接口(JVMPI for Java <= 1.4.2或JVMTI for Java> = 1.5.0)从正在运行的Java应用程序获取分析信息。

This amounts to some Sun supplied native code that gives a profiler hooks into the JVM.

这相当于一些Sun提供的本机代码,它将探查器挂钩到JVM中。

#3


If you only need a quick stack trace of your running application to find out which threads are blocking the JVM exit, you can send it the QUIT signal.

如果您只需要对正在运行的应用程序进行快速堆栈跟踪以找出阻止JVM出口的线程,则可以向其发送QUIT信号。

$ kill -QUIT <pid of java process>

Under Windows you need to run the application in a console window (using java.exe, not javaw.exe), then you can press Ctrl-Pause to generate the stack dump. In both cases it’s written to stdout.

在Windows下,您需要在控制台窗口中运行应用程序(使用java.exe,而不是javaw.exe),然后您可以按Ctrl-Pause来生成堆栈转储。在这两种情况下,它都写入stdout。

#4


I use Visual VM to monitor the JVM. Has lots of features, give it a try.

我使用Visual VM来监视JVM。有很多功能,试一试。

#5


I think you need a Java thread dump. This should list all threads with what they are doing at the moment. I had a similar problem myself, which a thread dump helped solve (Quartz scheduler threads, which did not exit when Tomcat finished).

我认为你需要一个Java线程转储。这应列出所有线程与他们目前正在做的事情。我自己也有类似的问题,一个线程转储有助于解决(Quartz调度程序线程,当Tomcat完成时它没有退出)。

#1


You can indeed get a stack trace of all running Threads dumped to the stdout by using kill -QUIT <pid> on a *NIX like OS, or by running the application in a Windows console and pressing Ctrl-Pause (as another poster notes.)

您确实可以通过在类似操作系统的* NIX上使用kill -QUIT ,或者通过在Windows控制台中运行应用程序并按Ctrl-Pause(另一张海报备注)来获取转储到stdout的所有正在运行的线程的堆栈跟踪。 )

However, it seems like you're asking for programmatic ways to do it. So, assuming what you really want is the set of all Threads who's current call stacks include one or more methods from a given class...

但是,您似乎要求以编程方式执行此操作。因此,假设您真正想要的是当前调用堆栈的所有线程的集合包括来自给定类的一个或多个方法...

The best thing I can find that doesn't involve calls into the JVMTI is to inspect the stacks of all running threads. I haven't tried this, but it should work in Java 1.5 and later. Keep in mind that this is, by definition, not AT ALL thread-safe (the list of running threads - and their current stack traces - are going to constantly change underneath you...lots of paranoid stuff would be necessary to actually make use of this list.)

我能找到的最好的事情是不涉及对JVMTI的调用是检查所有正在运行的线程的堆栈。我没有试过这个,但它应该在Java 1.5及更高版本中运行。请记住,根据定义,这不是所有线程安全的(正在运行的线程列表 - 以及它们当前的堆栈跟踪 - 将在您下面不断变化...实际使用时需要大量偏执的东西这个清单。)

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;
}

Let me know if this approach works out for you!

如果这种方法适合你,请告诉我!

#2


From this page,

从这个页面,

A Java profiler uses a native interface to the JVM (the JVMPI for Java <=1.4.2 or the JVMTI for Java >=1.5.0) to get profiling information from a running Java application.

Java探查器使用JVM的本机接口(JVMPI for Java <= 1.4.2或JVMTI for Java> = 1.5.0)从正在运行的Java应用程序获取分析信息。

This amounts to some Sun supplied native code that gives a profiler hooks into the JVM.

这相当于一些Sun提供的本机代码,它将探查器挂钩到JVM中。

#3


If you only need a quick stack trace of your running application to find out which threads are blocking the JVM exit, you can send it the QUIT signal.

如果您只需要对正在运行的应用程序进行快速堆栈跟踪以找出阻止JVM出口的线程,则可以向其发送QUIT信号。

$ kill -QUIT <pid of java process>

Under Windows you need to run the application in a console window (using java.exe, not javaw.exe), then you can press Ctrl-Pause to generate the stack dump. In both cases it’s written to stdout.

在Windows下,您需要在控制台窗口中运行应用程序(使用java.exe,而不是javaw.exe),然后您可以按Ctrl-Pause来生成堆栈转储。在这两种情况下,它都写入stdout。

#4


I use Visual VM to monitor the JVM. Has lots of features, give it a try.

我使用Visual VM来监视JVM。有很多功能,试一试。

#5


I think you need a Java thread dump. This should list all threads with what they are doing at the moment. I had a similar problem myself, which a thread dump helped solve (Quartz scheduler threads, which did not exit when Tomcat finished).

我认为你需要一个Java线程转储。这应列出所有线程与他们目前正在做的事情。我自己也有类似的问题,一个线程转储有助于解决(Quartz调度程序线程,当Tomcat完成时它没有退出)。