4

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

是的,我知道您可以对theads 进行守护,这样它们就不会阻止应用程序退出。但这确实让我想知道这是否可能。我能做的最接近的事情是类加载器(受保护!)findLoadedClass,尽管您必须运行自己的类加载器才能做到这一点。

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

4

5 回答 5

5

您确实可以通过kill -QUIT <pid>在 *NIX 之类的操作系统上使用或通过在 Windows 控制台中运行应用程序并按下Ctrl-Pause(作为另一张海报说明)来获取转储到标准输出的所有正在运行的线程的堆栈跟踪。

但是,您似乎在要求以编程方式来做到这一点。因此,假设您真正想要的是当前调用堆栈中包含来自给定类的一个或多个方法的所有线程的集合......

我能找到的最好的不涉及调用 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;
}

让我知道这种方法是否适合您!

于 2009-01-07T21:04:07.110 回答
3

这个页面

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

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

于 2009-01-07T18:41:22.423 回答
2

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

$ kill -QUIT <pid of java process>

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

于 2009-01-07T19:35:40.580 回答
1

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

于 2009-01-07T18:29:03.243 回答
0

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

于 2009-01-07T18:41:09.147 回答