从 Java 内部监控 Java
-
06-07-2019 - |
题
我想通过将程序的方法调用显示为树的分支来编写 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,以便线程将其堆栈打印到 我的 PrintStream,但这感觉有点不对。
有一个更好的方法吗?我可以使用任何预先存在的类/方法吗?
另外,我目前正在下载 Java 源代码,以检查线程类如何准确地打印其堆栈,以便我可以子类化线程并使用我自己的 getStack() 方法来模仿 dumpStack() 方法。
解决方案 2
哦,拍摄,看看源代码,我注意到线程类有一个方法public StackTraceElement [] getStackTrace(),它只是不在我正在阅读的文档中。现在我感到愚蠢。
所以是的,这似乎是解决方案。
其他提示
另请参阅最新Java版本附带的VisualVM。
一种方法可能是使用像 BCEL 这样的方法来预处理目标字节码以插入调用你自己的代码在每个方法入口和出口(可能最好通过将整个方法包装在try / finally块中来退出,以捕获异常退出)。由此,您可以完全按照实际情况推断出调用树。
看看 线程MXBean 类——我提供你所需要的。本质上,你:
- 调用 ManagementFactory.getThreadMXBean() 获取 ThreadMXBean 的实例;
- 对生成的 ThreadMXBean 调用 getAllThreadIds() 以枚举当前线程;
- 调用 getThreadInfo() 从给定的线程列表中获取前 n 个堆栈跟踪元素。
不隶属于 StackOverflow