如何跟踪 Java 中的方法调用?
How do I trace methods calls in Java?
考虑下面两个简单的 Java 类:
第一个例子
class Computer {
Computer() {
System.out.println("Constructor of Computer class.");
}
void On() {
System.out.println("PC turning on...");
}
void working() {
System.out.println("PC working...");
}
void Off() {
System.out.println("PC shuting down...");
}
public static void main(String[] args) {
Computer my = new Computer();
Laptop your = new Laptop();
my.On();
my.working();
your.On();
your.working();
my.Off();
your.Off();
}
}
第二个例子
class Laptop {
Laptop() {
System.out.println("Constructor of Laptop class.");
}
void On() {
System.out.println("Laptop turning on...");
}
void working() {
System.out.println("Laptop working...");
}
void Off() {
System.out.println("Laptop shuting down...");
}
}
程序结束后运行,如何跟踪(1)哪个对象调用了哪个方法(2)调用了多少次?
稍微精确一点,我可能有 100 类 和 1000 个对象,每个对象调用 100 个方法。我希望能够跟踪(在我 运行 程序之后)哪个对象调用了哪个方法以及调用了多少次。
感谢任何建议。
这为所有线程中所有对象的每个方法调用打印一行:
Runtime.traceMethodCalls() (deprecated / no-op in Java 9)
和
Runtime.traceInstructions (deprecated / no-op in Java 9)
您可以使用呼叫跟踪器,例如 housemd or btrace or inTrace
对于更复杂的分析,您可以使用如下之一的调用图实用程序:
(这里有关于这个主题的article)
上面已弃用的方法将被删除,因为现在有特定于 JVM 的替代方法:
- Java Flight Recorder JDK 7 的一部分,从 build 56 开始。需要商业许可才能在 生产 中使用
- VisualVM Free/popular 第三方
这两种工具都非常易于设置和开始收集信息,并且具有漂亮的 GUI 界面。它们附加到 运行 JVM 进程并允许线程快照和各种其他类型的诊断(Visual VM 有很多可用的插件,但如果你想超越,可能需要一段时间来整理配置和理解默认行为,而 JFR 默认情况下使用更多工具)。
此外,不要低估 JVM 分布式命令行实用程序 ($JAVA_HOME/bin
) 在执行一些易于访问的诊断方面的用处。
$ jdb -classpath ... -sourcepath ... my.App
jdb> stop on my.App.main
jdb> run
jdb> step <... repeat until get to interesting line...>
jdb> threads
jdb> trace go methods 0x1 <... 0x1 is our main thread ID ...>
jdb> step
<...HERE you get full methods calls trace...>
jdb> quit
考虑下面两个简单的 Java 类:
第一个例子
class Computer {
Computer() {
System.out.println("Constructor of Computer class.");
}
void On() {
System.out.println("PC turning on...");
}
void working() {
System.out.println("PC working...");
}
void Off() {
System.out.println("PC shuting down...");
}
public static void main(String[] args) {
Computer my = new Computer();
Laptop your = new Laptop();
my.On();
my.working();
your.On();
your.working();
my.Off();
your.Off();
}
}
第二个例子
class Laptop {
Laptop() {
System.out.println("Constructor of Laptop class.");
}
void On() {
System.out.println("Laptop turning on...");
}
void working() {
System.out.println("Laptop working...");
}
void Off() {
System.out.println("Laptop shuting down...");
}
}
程序结束后运行,如何跟踪(1)哪个对象调用了哪个方法(2)调用了多少次?
稍微精确一点,我可能有 100 类 和 1000 个对象,每个对象调用 100 个方法。我希望能够跟踪(在我 运行 程序之后)哪个对象调用了哪个方法以及调用了多少次。
感谢任何建议。
这为所有线程中所有对象的每个方法调用打印一行:
Runtime.traceMethodCalls() (deprecated / no-op in Java 9)
和
Runtime.traceInstructions (deprecated / no-op in Java 9)
您可以使用呼叫跟踪器,例如 housemd or btrace or inTrace
对于更复杂的分析,您可以使用如下之一的调用图实用程序:
(这里有关于这个主题的article)
上面已弃用的方法将被删除,因为现在有特定于 JVM 的替代方法:
- Java Flight Recorder JDK 7 的一部分,从 build 56 开始。需要商业许可才能在 生产 中使用
- VisualVM Free/popular 第三方
这两种工具都非常易于设置和开始收集信息,并且具有漂亮的 GUI 界面。它们附加到 运行 JVM 进程并允许线程快照和各种其他类型的诊断(Visual VM 有很多可用的插件,但如果你想超越,可能需要一段时间来整理配置和理解默认行为,而 JFR 默认情况下使用更多工具)。
此外,不要低估 JVM 分布式命令行实用程序 ($JAVA_HOME/bin
) 在执行一些易于访问的诊断方面的用处。
$ jdb -classpath ... -sourcepath ... my.App
jdb> stop on my.App.main
jdb> run
jdb> step <... repeat until get to interesting line...>
jdb> threads
jdb> trace go methods 0x1 <... 0x1 is our main thread ID ...>
jdb> step
<...HERE you get full methods calls trace...>
jdb> quit