【发布时间】:2011-05-10 13:15:42
【问题描述】:
由于源代码,这个问题有点长,我尽量简化了。请多多包涵,感谢您的阅读。
我有一个带有可能运行数百万次循环的应用程序。与其在该循环中调用数千到数百万个malloc/free,不如先调用一个malloc,然后再调用数千到数百万个realloc。
但是当我使用realloc 时,我遇到了一个问题,即我的应用程序消耗了几 GB 的内存并自行终止。如果我使用malloc,我的内存使用情况很好。
如果我使用valgrind 的memtest 在较小的测试数据集上运行,它会报告malloc 或realloc 没有内存泄漏。
我已验证我将每个malloc-ed(然后是realloc-ed)对象与相应的free 匹配。
所以,理论上,我没有泄漏内存,只是使用 realloc 似乎消耗了我所有的可用 RAM,我想知道为什么以及我可以做些什么来解决这个问题。
我最初拥有的是这样的东西,它使用malloc并且可以正常工作:
Malloc 代码
void A () {
do {
B();
} while (someConditionThatIsTrueForMillionInstances);
}
void B () {
char *firstString = NULL;
char *secondString = NULL;
char *someOtherString;
/* populate someOtherString with data from stream, for example */
C((const char *)someOtherString, &firstString, &secondString);
fprintf(stderr, "first: [%s] | second: [%s]\n", firstString, secondString);
if (firstString)
free(firstString);
if (secondString)
free(secondString);
}
void C (const char *someOtherString, char **firstString, char **secondString) {
char firstBuffer[BUFLENGTH];
char secondBuffer[BUFLENGTH];
/* populate buffers with some data from tokenizing someOtherString in a special way */
*firstString = malloc(strlen(firstBuffer)+1);
strncpy(*firstString, firstBuffer, strlen(firstBuffer)+1);
*secondString = malloc(strlen(secondBuffer)+1);
strncpy(*secondString, secondBuffer, strlen(secondBuffer)+1);
}
这很好用。但我想要更快的东西。
现在我测试一个realloc 排列,其中malloc-s 只有一次:
重新定位代码
void A () {
char *firstString = NULL;
char *secondString = NULL;
do {
B(&firstString, &secondString);
} while (someConditionThatIsTrueForMillionInstances);
if (firstString)
free(firstString);
if (secondString)
free(secondString);
}
void B (char **firstString, char **secondString) {
char *someOtherString;
/* populate someOtherString with data from stream, for example */
C((const char *)someOtherString, &(*firstString), &(*secondString));
fprintf(stderr, "first: [%s] | second: [%s]\n", *firstString, *secondString);
}
void C (const char *someOtherString, char **firstString, char **secondString) {
char firstBuffer[BUFLENGTH];
char secondBuffer[BUFLENGTH];
/* populate buffers with some data from tokenizing someOtherString in a special way */
/* realloc should act as malloc on first pass through */
*firstString = realloc(*firstString, strlen(firstBuffer)+1);
strncpy(*firstString, firstBuffer, strlen(firstBuffer)+1);
*secondString = realloc(*secondString, strlen(secondBuffer)+1);
strncpy(*secondString, secondBuffer, strlen(secondBuffer)+1);
}
如果我在使用导致百万循环条件的大型数据集运行此基于realloc 的测试时在命令行上查看free -m 的输出,我的内存将从4 GB 下降到0并且应用崩溃了。
使用realloc 导致这种情况我错过了什么?对不起,如果这是一个愚蠢的问题,并提前感谢您的建议。
【问题讨论】:
-
你也可以显示 strace 的输出吗?知道系统调用 realloc 与 malloc/free 映射到什么上会很有启发性。
-
您可能想研究一个自定义分配函数,该函数基本上通过 malloc() 获取一个大块并将其作为自定义堆空间进行管理。这是一种老派,但如果你知道自己在做什么,它会很好地工作。