为什么会在strace输出brk()需要几秒钟?

迁移到Ubuntu Hardy(amd64)时,我们发现其中一个应用程序的速度显着下降。 它在Debian Sarge i386上运行得非常好。

对(Apache 1.3)httpd进程运行'strace -r'显示了以下令人不安的部分:

      0.000083 poll([{fd = 8,events = POLLIN | POLLERR,revents = POLLIN}],1,-1)= 1
      0.000026 recvfrom(8,“_323-412D \ 0 \ 0 \ 0000 \ 0 \ 2 \ 0 \ 0 \ 0 \ 17recueil-cours”...,32727,0,NULL,NULL)= 8192
      0.000061 poll([{fd = 8,events = POLLIN | POLLERR,revents = POLLIN}],1,-1)= 1
      0.000026 recvfrom(8,“\ 0 \ 0 \ 0000 \ 0 \ 2 \ 0 \ 0 \ 0 \ 17recueil-courses \ 0 \ 0 \ 0 \ 23er2”...,32767,0,NULL,NULL)= 2369
      0.117422 brk(0x397a000)= 0x397a000
      0.140721 brk(0x399b000)= 0x399b000
      4.457037 brk(0x39bc000)= 0x39bc000
      (st_mode = S_IFREG | 0644,st_size = 2194,...})= 0

注意最后一行的brk – 暗示brk(0x399b000)花费了4.45秒!

我已经检查了brk的手册页,指向它用于请求更大的数据段/堆,但是我找不到任何理由需要这么长时间。

任何人有任何想法?

它发现这个问题主要是由于我对strace -r输出的误解。

'-r'选项提供上次系统调用以来的时间(以秒为单位),而不是最后一次系统调用执行的时间。

在这种情况下,CPU正在执行一些计算,而不是处理brk()。

现在这个问题已经解决 – 这是由于升级到perl 5.8.9(来自perl 5.8.8)造成的。 我们已经退出了perl升级,稍后将会研究perl 5.8.9减速的原因。

brk()是malloc如何扩展其可用的内存池。 这意味着内核可以交换或者玩内存shell游戏来find一个足够大的新的内存段来回传,所以性能是不可预测的。 也就是说,你可能想看看一些内存使用可调参数(sysctl -a | grep ^ vm应该给你一个开始寻找的好地方)来改变你的内存分配策略。