Linux

為什麼 strace 輸出中的 brk() 需要幾秒鐘?

  • June 6, 2009

我們注意到我們的一個應用程序在遷移到 Ubuntu Hardy amd64 時顯著放緩。它在 Debian Sarge i386 上執行良好。

對(Apache 1.3)httpd 程序執行“strace -r”顯示了以下令人不安的部分:

0.000083 輪詢([{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 輪詢([{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
0.078792 stat("/opt/semantico/slot/nijhoff/3/sitecode/live/public_home.html", {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 擴展其可用記憶體池的方式。這意味著核心可能正在交換或玩記憶體外殼遊戲以找到足夠大的新記憶體段來交回,因此性能是……不可預測的。也就是說,您可能希望查看一些記憶體使用可調參數(sysctl -a | grep ^vm 應該為您提供一個很好的起點)來更改您的記憶體分配策略。

引用自:https://serverfault.com/questions/13012