我正在使用YourKit和JProfiler中的采样分析来分析程序,并且还“手动”(我启动它并按Ctrl-Break几次以获取线程转储)。
这三种方法给我带来了非常奇怪的结果:在3行方法中花费了几十个百分点甚至没有进行任何分配或同步,也没有循环等。在我将这个方法变成NOP并完全删除它的调用之后,可观察的程序性能根本没有改变(虽然它有一个可以忽略不计的内存泄漏,因为它是一种释放廉价资源的方法)。
我认为这可能是因为JVM对可能采用线程堆栈跟踪的时刻施加的约束,并且它在某种程度上证明了在我的程序中它恰好是调用此方法的时刻,虽然它没有什么特别之处或它被调用的上下文。
这种现象可以解释什么? 上述限制是什么? 我可以采取哪些进一步的措施来澄清情况?
答案 0 :(得分:0)
在我看来,这些结果只表明这种方法被调用了很多次。由于它的代码非常小,并且可能被称为调用树叶,因此它对分析结果的影响似乎是可以忽略的。但是,我有很多时间都有这种奇怪的结果。
答案 1 :(得分:0)
当您多次执行Ctrl-Break并获得线程转储时,我很好奇您所看到的内容。在我看来,调用堆栈是最有用的信息。如果您的3-liner在堆栈上占用了大部分时间,那么您可以通过查看调用它的位置,以及从哪里调用来了解原因等等。这些调用站点只是负责3班的时间。
如果堆栈跟踪似乎毫无意义,可能是因为它们被推迟到完成某些事情之后。如果是这样,请查看堆栈以查看刚刚完成的内容,因为中断可能已发生。
答案 2 :(得分:0)
由于意外的使用模式,某些第三方库导致堆转储完全失控,例如,如果使用cglib,它将掩盖问题的实际原因,而是显示大量的Proxy对象(如果我没记错)填写VM。
简而言之,代码生成和反射可能会导致统计信息出错。