如何在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()(Java 9中已弃用/无操作) 

  Runtime.traceInstructions(Java 9中已弃用/无操作) 

您可以使用像housemdbtraceinTrace这样的呼叫跟踪器

对于更复杂的分析,您可以使用调用图实用程序,如下所示:

  • javashot

  • Java的调用图

(这是一篇关于这个主题的文章

上面已弃用的方法将被删除,因为现在有特定于JVM的替代方法:

  • Java Flight Recorder 从构建版本56开始的JDK 7的一部分。需要商业许可证才能在生产中使用
  • VisualVM 免费/流行的第三方

这两个工具都很容易设置并开始收集信息并具有良好的GUI界面。 它们附加到正在运行的JVM进程并允许线程快照和各种其他类型的诊断(Visual VM有很多可用的插件,但如果你想超越默认行为,可能需要一段时间才能进行排序以进行配置和理解,而JFR默认配备更多)。

此外,不要低估JVM分布式命令行实用程序( $JAVA_HOME/bin )的有用性,以执行一些易于访问的诊断。

  • jstack 堆栈跟踪
  • jmap 内存映射
  • jstat JVM统计监控
  • jhat 堆分析工具
  • jdb 调试器
  • jinfo java进程或核心文件配置信息
 $ 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