2011-09-14 49 views
0
Environment: uname -a: 2.6.38 #18 Thu Apr 28 12:38:48 CEST 2011 armv5tejl GNU/Linux 
    GCC: 
    gcc -v 
    Using built-in specs. 
    Target: arm-linux-gnueabi 
    Configured with: ../src/configure -v --with-pkgversion='Debian 4.4.5-8' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.4 --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --disable-sjlj-exceptions --enable-checking=release --build=arm-linux-gnueabi --host=arm-linux-gnueabi --target=arm-linux-gnueabi 
    Thread model: posix 
    gcc version 4.4.5 (Debian 4.4.5-8) 

在下面的代码中,我似乎正在做的一切正常,但分配的内存显然没有被释放。我的结构方法不是一个链表。释放动态结构不释放内存

我说:“很明显”,了解垃圾回收将采取行动以恣任何时候。不过,正如我看到RSS在测试代码运行时逐渐增加,并且由于它在每个测试中分配相同的空间量,我认为分配将被重新使用。

我的代码实现了一个简单的动态结构:

struct _aemErrors 
{ 
    int stored; // true = stored to sql 
    int mailed; // true = mailed to alert 
    int nType; // LOG_DEBUG LOG_INFO... 
    int time; // error triggered timestamp 
    int line; // line in file that triggered 
    char *cFunction; // function that triggered 
    char *cDesc; // description of problem 
}; 
struct _aemErrors **aemErrors; 
int aemErrorsCount; 

该结构具有在使用时,与任一的malloc()或的strdup()

结构的每个记录创建了两个字符指针初始化与此:

int AddaemError(void) 
{ 
    ++aemErrorsCount; 
    aemErrors = (struct _aemErrors **)realloc(aemErrors, (aemErrorsCount+1) *  sizeof(struct _aemErrors *)); 
    aemErrors[aemErrorsCount] = (struct _aemErrors *)malloc(sizeof(struct _aemErrors)); 
    return(aemErrorsCount); 
} 

所以:

int main(int argc,char **argv) 
{ 

    // initialize the structure 
    aemErrors=NULL; 
    aemErrorsCount=-1; 

    int nPtr=0; 
    int nLoopCount=0; 
    while (nLoopCount<100) 
    { 

    for (nPtr=0;nPtr<1000;nPtr++) 
     { 
     nPtr=AddaemError(); 
     aemErrors[nPtr]->stored=false; 
     aemErrors[nPtr]->mailed=false; 
     aemErrors[nPtr]->nType=LOG_ALERT; 
     aemErrors[nPtr]->nTime=time(NULL); 
     aemErrors[nPtr]->line=0; 
     aemErrors[nPtr]->cFunction=strdup("ThisIsATest"); 
     aemErrors[nPtr]->cDesc=strdup("ThisIsATest"); 
    } 
    FreeaemErrors(); 
    sleep(5); 
    ++nLoopCount; 
    } 
    return(0); 
} 

随着环路旋转,我看到RSS相应增加。我正在使用内部内存状态测试器(未显示:读取proc文件系统数据),还使用封装运行时的外部外壳进程,并且每秒都会为我提供内存性能数据。注意:问题在没有监控的情况下发生,所以我知道这不会影响结果。

现在,我想免费的一切:

// cleanup the dynamic structure 
int FreeaemErrors(void) 
{ 
    if (aemErrors==NULL) 
     return(true); 
    int i=0; 

    printf("FreeaemErrors():Count=%i\n",aemErrorsCount); 

    for(i = 0; i <= aemErrorsCount; i++) 
    { 
     free(aemErrors[i]->cFunction); 
     free(aemErrors[i]->cDesc); 
     free(aemErrors[i]); 
     aemErrors[i]->cFunction=NULL; 
     aemErrors[i]->cDesc=NULL; 
     aemErrors[i]=NULL; 
    } 
    printf("Done. Free root\n"); 
    free(aemErrors); 
    aemErrors=NULL; 
    aemErrorsCount=-1; 
    printf("Returning\n"); 
    return(true); 
} 

所以我发出FreeaemErrors();然后等待几秒钟,观看记忆。它不会减少。

,下一次我运行填入循环,增加另外1000条记录的所谓清洁结构,RSS再次上升。

我现在有点慌张。

想法,任何人?


感谢您的输入。

相当多的各种结构规格的测试后,我发现,一旦我们达到一定的规模,然后免费应有尽有,RSS落户回到近,我希望它是。但不完全。

我学到了一些关于内存碎片,以及如何时,在我的例子,发生realloc()的,因为新的分配连续的内存是不可用的程序可以膨胀。

响应涉及的(a)初始化我的结构尺寸这个问题以保持n个元素的块(n为40〜100,根据需要); (b)当结构需要增长时(我们用完了初始分配),我复制原始结构,完全释放原始数据,然后分配一个大小为n + increment_size的新结构,然后从旧的,然后解放旧的。在分配计数内有新的记录请求的情况下,我所有的功能都会返回当前的分配编号。

新方案根本不使用realloc()。鉴于这个问题,我认为这是一个加分。

复杂,也许在某些情况下会很慢,但至少记忆似乎在检查。

+3

你有没有听说过purify的工具?我没有倾向于浏览所有的代码。也许你可以缩小一点。 –

+1

Your're在AddaemError()中增加aemErrorCount,然后再分配一个空间,这意味着你永远不会在数组中使用元素[0],但是你可以释放它。你也在分配nPtr并在循环中增加它。这次虽然没有回答:) – tinman

+1

@tinman是对的。你也谈论“垃圾收集器”采取行动,什么垃圾收集器?你对“观看记忆”意味着什么?它不会减少?你在看“top”的输出还是什么? – user786653

回答

1

使用freerealloc释放内存并不意味着将其返回系统。堆机器只会将这些页面保留在某个地方,以便它们可用于下一次分配。如果你真的想知道你是否可以正确释放所有内存,请使用valgrind之类的工具。这将告诉你“postmortem”,如果你的进程释放了它分配的所有内存,或者如果没有,它会指向你的代码中分配的位置,而不会随后释放。