perf - 性能报告解读

标签 perf

我展示了使用 perf -g -p 收集的样本的 perf 报告 的输出。我不知道如何实现第一列。有很多 Java_* 调用花费了超过 90% 的时间。

如何解读? enter image description here


在呈现的结果中有很多条目,我的意思是:

+ 98,78%     0,00%             java       libpthread-2.26.so
+ 95,77%     0,00%             java       libjvm.so 
...

我的问题是:

为什么这样的条目多于 1 个?每个条目都是一种堆栈跟踪。单线程进程只有一个堆栈跟踪。

最佳答案

您在此处引用的列表:

+ 98,78%     0,00%             java       libpthread-2.26.so
+ 95,77%     0,00%             java       libjvm.so 

...

And my question is:

Why is there more such entries than 1? Every entry is a kind of stacktrace. The one-threaded process has exactly one stacktrace.

不是堆栈跟踪吗?它是运行期间任何示例的任何堆栈跟踪中出现的函数列表。仅当您展开该列表的一个元素时,您才能看到包含该函数的堆栈跟踪的组合 TreeView 。

我不确定你的意思单线程进程只有一个堆栈跟踪。任何进程在其生命周期内都会有各种堆栈跟踪,即使它只有一个线程。例如,在启动时,堆栈跟踪将只是 main() ,并且尽快 main()调用函数,堆栈跟踪会更改以包含该函数等等。

现在在函数列表中,第一列显示总开销,包括所有子函数(即,包括此函数调用的函数)。由于几乎所有有趣的工作都发生在共享相同最外层函数的调用链中,因此顶层是一种无用的列表,其中显示的许多函数的开销超过 90%。

第二列是“自己的”开销,这意味着在该方法中实际花费的时间1不是任何子方法。对于所有顶级方法来说,该值接近于零,因此真正的工作发生在这些方法调用的某些方法中,而不是这些方法本身。

您在顶部展开的 TreeView 确实告诉您需要了解的内容:~94% 的时间花在 radek.queue.wlQueue.writeBytes() 的内部/下面。 ,而那个家伙大部分时间都花在 String.intern() 上。 。所以这里的瓶颈是所有String.intern()调用,可能是因为字符串表太小,或者只是因为 String.intern()只是generally sucks用于重复数据删除。我这里的一般规则是使用 Guava 的 Interner<String>除非您特别需要文字字符串与内部字符串共享相同字符串池的属性(即 "foo" == new String("foo").intern() )。


1 我在这里宽松地说“时间量” - 它实际上是您指定给 perf record 的任何事件的总样本的分数。 - 但默认情况下,这应该大约是 CPU 时间。

关于perf - 性能报告解读,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48957480/

相关文章:

linux - 是否可以在每个内核的基础上测量单个进程消耗的周期?

linux - 使用 perf 测量到达主函数的时间?

compiler-errors - SYS_futex的性能编译异常

fortran - 性能报告中的 __xl_pow、__xl_log、__xl_exp

linux - 如何衡量一个程序是否在 Linux 中的多个内核上并行运行?

linux - perf stat 周期数和频率缩放

linux - 使用 linux perf 和 PEBS 对程序中的内存访问进行采样

c++ - 如何使 perf_event_open() 中的 PERF_COUNT_SW_CONTEXT_SWITCHES 配置起作用?

linux - systemtap:如何确定探测事件和参数