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

Java 在正在运行的JVM中查找正在运行的实例,java,jvm,classloader,Java,Jvm,Classloader,我想知道是否有可能获得给定类的运行实例的句柄。触发此问题的特定问题是,由于大量正在运行的线程,应用程序无法很好地退出 是的,我知道您可以将thead后台监控,这样它们就不会阻塞应用程序出口。但这确实让我怀疑这是否可能。我能做的最接近的事情是类加载器(受保护!),尽管您必须运行自己的类加载器才能做到这一点 另一方面,这就是分析工具跟踪对象句柄的方式吗?通过运行他们自己的自定义类加载器?还是有一些我看不到的巧妙的方式 我用来监视JVM。有很多功能,试试看。我想你需要一个。这应该列出所有线程及其当前正

我想知道是否有可能获得给定类的运行实例的句柄。触发此问题的特定问题是,由于大量正在运行的线程,应用程序无法很好地退出

是的,我知道您可以将thead后台监控,这样它们就不会阻塞应用程序出口。但这确实让我怀疑这是否可能。我能做的最接近的事情是类加载器(受保护!),尽管您必须运行自己的类加载器才能做到这一点

另一方面,这就是分析工具跟踪对象句柄的方式吗?通过运行他们自己的自定义类加载器?还是有一些我看不到的巧妙的方式

我用来监视JVM。有很多功能,试试看。

我想你需要一个。这应该列出所有线程及其当前正在执行的操作。我自己也有一个类似的问题,线程转储帮助解决了这个问题(Quartz调度程序线程,在Tomcat完成时不会退出)


Java探查器使用JVM的本机接口(JVMPI for Java如果您只需要对正在运行的应用程序进行快速堆栈跟踪,以找出哪些线程阻止JVM退出,则可以向其发送退出信号

$ kill -QUIT <pid of java process>
$kill-退出

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

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

但是,您似乎在寻求编程方式来实现它。因此,假设您真正想要的是当前调用堆栈包含给定类中一个或多个方法的所有线程集

我能找到的最好的不涉及JVMTI调用的方法是检查所有运行线程的堆栈。我没有尝试过这一方法,但它应该在Java 1.5及更高版本中工作。请记住,根据定义,这根本不是线程安全的(运行线程的列表——以及它们当前的堆栈跟踪——将在你下面不断变化……要真正利用这个列表,需要很多偏执的东西。)

公共集FindThreadsRunning类(类classToFindRunning){
Set runningThreads=new HashSet();
字符串className=classToFindRunning.getName();
Map stackTraces=Thread.getAllStackTraces();
对于(线程t:stackTraces.keySey()){
StackTraceElement[]steArray=stackTraces.get(t);
对于(int i=0;i
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;
}