Java中的简单动态调用图

Java中的简单动态调用图,java,code-analysis,graphviz,callstack,Java,Code Analysis,Graphviz,Callstack,我正在寻找一个简单的Java动态调用图记录器,您可以添加几行代码。我知道有一个问题。此外,我还帮助Zola开发了一个类似的工具,因此我可以重写一个类似的工具,但我不想深入研究JVM的内部结构 现在有没有比AspectJ解决方案更稳定、更好的开源解决方案 这样做的目的是作为单元测试代码中某些部分的辅助工具,您需要更多关于其行为的信息。我认为您需要通过任何可能的方式收集调用图(而不仅仅是一组调用) 可以使用静态分析器(如果您可以使用足够强大的分析器)来收集潜在的调用图。动态方法通过检测代码在运行时收

我正在寻找一个简单的Java动态调用图记录器,您可以添加几行代码。我知道有一个问题。此外,我还帮助Zola开发了一个类似的工具,因此我可以重写一个类似的工具,但我不想深入研究JVM的内部结构

现在有没有比AspectJ解决方案更稳定、更好的开源解决方案


这样做的目的是作为单元测试代码中某些部分的辅助工具,您需要更多关于其行为的信息。

我认为您需要通过任何可能的方式收集调用图(而不仅仅是一组调用)

可以使用静态分析器(如果您可以使用足够强大的分析器)来收集潜在的调用图。动态方法通过检测代码在运行时收集一个。有些人可能特别想要动态的,因为他们想看到一组特定输入数据的实际调用图

有几个Java探查器将动态收集这些信息,包括。据我所知,没有一个是开源的,但我可能错了

这类分析器通常通过检测代码(如果语言[例如Java、C#]具有源代码或VM代码)来工作。他们如何做到这一点取决于供应商。 在我们的例子中,我们使用我们的方法将源代码从其原始形式转换为也收集分析数据的形式


您也可以使用AspectJ插入插装来完成此操作。[值得注意的是,方面只是程序转换的一个特例]。当然,除了检测代码,还有更多的工作要做;您必须高效地收集运行时数据,并在执行过程之后生成调用图。所以做这一切需要做一点工作,但从你的发光体验中你大概知道这一点

有通过本机JVMTI C/C++的指令插入。就像我说的,我想留在纯Java


Java确实有一个Runtime.getRuntime().traceMethodCalls(),但您仍然需要一些东西来使用输出。

可能是离题的,但您确定确实需要调用图吗?不知何故,我认为这样一个详细的图表在一个大小合理的应用程序中几乎是无用的。我发现更有用的是类之间的依赖关系图,只要使用某种依赖关系注入,就很容易得到这种关系图。我使用了GoogleGuice(实际上,重组/保持一个合理大小的应用程序非常有用)


有一个非常好的google guice依赖关系图示器,可以免费提供:。我甚至定制了它(扩展了Grapher类),用不同的颜色标记不同的类类型(DAO、控制器、API等)…

我对动态日志更感兴趣,因为我希望边存储为计数器,所以我可以使用调用图作为某种东西的马尔可夫链。Glow实际上只开发了几天。GCC具有记录函数调用的钩子。主要的挂起是ADDR2Load不工作在OSX上,C++的二进制兼容性被阻塞,所以你必须在C中编译部分然后编译C++部分。至于动态收集,它取决于你的程序。如果函数调用边是稀疏的,则不会有二次空间来存储边。对于每条边,它只是一个计数器(除非您也记录时间戳),因此每条边的complextiy就是log(#of calls)。观察:如果没有函数指针魔术(或转到函数外部),带有计数器注释边的动态调用图的大小将有一个上限O(SizeOfSourceCode*log(Runtime))。证明:编写一个IDE,在每个函数调用上方放置一条注释,并存储一个计数器。听起来你想跟踪调用位置,而不是函数之间的调用。我观察到对象是指针,所以实际上方法调用是通过函数指针进行的调用。动态调用图捕获的目的是捕获所有函数调用(源/目标),无论它们是否静态明显。如果您愿意只满足于静态明显的函数调用,是的,您可以预先分配所有需要的空间,并且运行时的复杂性可以是O(1)。部分正确。我打算做一些后处理来得到感兴趣的子图。谢谢你的链接!