【问题标题】:Monitoring Java from within Java从 Java 中监视 Java
【发布时间】:2010-12-09 16:34:50
【问题描述】:

我想通过将程序的方法调用显示为树的分支来编写 Java 程序的简单可视化。这可以很简单地通过让程序本身告诉可视化它正在做什么来完成,但我希望能够使用任何 Java 方法/类来做到这一点,而不仅仅是我修改的那些。

我需要的是能够观察程序调用的方法以及在该方法中调用了哪些方法等等。显然,堆栈跟踪正好提供了这个功能:

 java.lang.NullPointerException
     at MyClass.mash(MyClass.java:9)
     at MyClass.crunch(MyClass.java:6)
     at MyClass.main(MyClass.java:3)

所以我考虑让我要监视的程序在一个线程中运行,然后只查看该线程的堆栈。但是,线程类并不真正支持这一点。它只支持打印当前堆栈。

当然,现在我想简单地更改 System 类的 PrintStream,以便线程将其堆栈打印到 my PrintStream,但这感觉有点不对。

有没有更好的方法来做到这一点?我可以使用任何预先存在的类/方法吗?

另外,我目前正在下载 Java 源代码,以检查线程类如何准确地打印其堆栈,以便我可以将线程子类化并用我自己的 getStack() 方法模仿 dumpStack() 方法。

【问题讨论】:

  • 我知道它“感觉不对”,但事实并非如此——可以重定向 System.out(到写入文件的 PrintStream)我最终编写了自己的控制台,以前我做过现在已经有足够的时间知道所有这些都在库中,无论是在 java.util 中还是在其他任何地方:如果您可以在任何地方获得 dumpStack(),请将其转储到您想要的任何地方:这就是它的用途。跨度>

标签: java monitoring visualization monitor


【解决方案1】:

看看ThreadMXBean 课程——它可以满足您的需求。本质上,你:

  • 调用 ManagementFactory.getThreadMXBean() 获取 ThreadMXBean 的实例;
  • 在生成的 ThreadMXBean 上调用 getAllThreadIds() 以枚举当前线程;
  • 调用 getThreadInfo() 以从给定的线程列表中获取前 n 个堆栈跟踪元素。

【讨论】:

    【解决方案2】:

    还可以查看随最新 Java 版本发布的 VisualVM。

    【讨论】:

    • 您也可以将自己的自定义插件添加到此框架中,而无需太多麻烦。
    【解决方案3】:

    您可以为此使用AspectJ。看看这个description 正是你的用例。

    【讨论】:

      【解决方案4】:

      哎呀,看看源代码,我注意到线程类有一个方法 public StackTraceElement[] getStackTrace(),它只是不在我正在阅读的文档中。现在我觉得自己很笨。

      是的,这似乎是解决方案。

      【讨论】:

      • 这是一个“较新”的补充。您可能一直在查看 Java 1.4 javadoc。
      【解决方案5】:

      一种方法可能是使用 BCEL 之类的东西来预处理目标字节码,以便在每个方法进入和退出时插入对您自己代码的调用(最好通过将整个方法包装在 try/finally 块中来退出,捕获异常退出)。由此,您可以准确地推断出调用树。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-03
        • 2013-10-26
        • 2016-05-13
        • 2011-03-22
        • 1970-01-01
        相关资源
        最近更新 更多