【发布时间】:2012-07-30 21:55:54
【问题描述】:
我一直在研究调试分叉 TCP 服务器中的内存使用情况。我认为我做得很好,我似乎无法在“堆摘要”中找到有关“分配的字节数”的信息。我的服务器运行时间越长,这个数字似乎就在不断增加:
==27526==
==27526== HEAP SUMMARY:
==27526== in use at exit: 0 bytes in 0 blocks
==27526== total heap usage: 113 allocs, 113 frees, 283,043 bytes allocated
==27526==
==27526== All heap blocks were freed -- no leaks are possible
==27526==
==27526== For counts of detected and suppressed errors, rerun with: -v
==27526== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
==27528==
==27528== HEAP SUMMARY:
==27528== in use at exit: 0 bytes in 0 blocks
==27528== total heap usage: 120 allocs, 120 frees, 300,808 bytes allocated
==27528==
==27528== All heap blocks were freed -- no leaks are possible
==27528==
==27528== For counts of detected and suppressed errors, rerun with: -v
==27528== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
==27537==
==27537== HEAP SUMMARY:
==27537== in use at exit: 0 bytes in 0 blocks
==27537== total heap usage: 127 allocs, 127 frees, 318,573 bytes allocated
==27537==
==27537== All heap blocks were freed -- no leaks are possible
==27537==
==27537== For counts of detected and suppressed errors, rerun with: -v
==27537== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
虽然 Valgrind 报告 allocs 和 free 是相等的,并且没有泄漏是可能的,但我不相信分配的字节会增加。
那么:如果分配的字节数不断增加,这是否意味着即使 Valgrind 报告不可能发生泄漏,我也必须从某个堆中释放?
谢谢!
编辑: 有了 Gordon Bailey 的回答和其他提示,我仍然有点厌倦。写了这个小应用:
/* client.c */
#include <stdio.h>
void child_func(int childnum);
int main(int argc, char *argv[])
{
int nchildren = 1;
int pid;
int x;
if (argc > 1)
{
nchildren = atoi(argv[1]);
}
for (x = 0; x < nchildren; x++)
{
if ((pid = fork()) == 0)
{
child_func(x + 1);
exit(0);
}
}
wait(NULL);
return 0;
}
void child_func(int childnum)
{
int i;
for (i = 0; i < 1000; i++) {
free(malloc(1));
}
sleep(1);
}
当我运行这个 Valgrind 输出是:
==28245== HEAP SUMMARY:
==28245== in use at exit: 0 bytes in 0 blocks
==28245== total heap usage: 1,000 allocs, 1,000 frees, 1,000 bytes allocated
==28245==
==28245== All heap blocks were freed -- no leaks are possible
==28245==
==28245== For counts of detected and suppressed errors, rerun with: -v
==28245== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
==28246== HEAP SUMMARY:
==28246== in use at exit: 0 bytes in 0 blocks
==28246== total heap usage: 1,000 allocs, 1,000 frees, 1,000 bytes allocated
==28246==
==28246== All heap blocks were freed -- no leaks are possible
所以看起来堆上的所有内存都被清除了,并且与我的应用程序的输出肯定不同。
【问题讨论】:
-
您的服务器中是否存在依赖于历史记录的内容?程序的输入是确定性的吗?如果是这样,如果你给它完全相同的输入会发生什么?请注意,输入还包含它打开的所有文件。
-
不。服务器接受传入的连接,分叉自己来处理连接,解码数据并插入 Mysql 数据库。之后我退出分叉,不需要保留任何数据。我在 fork 上调用 exit,所以我认为它应该清除堆中的所有数据。
-
看起来这只是 Valgrinds 在应用程序生命周期内报告总使用内存的方式(从下面的两个答案判断)。我不知道为什么我想知道这个,但这就是生活。
-
嗯,你应该一定要留意它。
valgrind不应该依赖于它自己之前的调用。如果你的程序真的在每次调用中不断增加约 7.8Kb,那么有一天它最终会耗尽内存。我的建议是编写一个持续执行此测试的脚本,greptotal heap usage行并将其放入文件中。在晚上运行脚本,早上你会看到一组漂亮的数字。如果有模式,你就有麻烦了。 -
另外,
valgrind说 (抑制:2 from 2)。您是否尝试过对于检测到和抑制的错误计数,重新运行:-v?