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

Ste*_* B. 4 java jvm classloader

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

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

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

Jar*_*red 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;
}
Run Code Online (Sandbox Code Playgroud)

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