valgrind,总堆使用量不断增加

时间:2017-10-02 08:28:41

标签: c linux

请以下面的例子为例。 似乎没有内存泄漏,但为什么总堆使用和分配的字节数不断增加? 如果我删除第一部分(test1),则valgrind结果不显示任何增加的堆并且总是显示总堆使用量:1个allocs,1个frees,568个字节分配

代码示例:

int main(void)
{
    while(1)
    {
        FILE *test1;
        test1 = fopen("test1", "w");
        fprintf(test1, "something\n");
        fclose(test1);

        pid_t childPid; 
        childPid = fork();
        if(childPid == 0)
        {
            int j;
            FILE *test2;
            test2 = fopen("test2", "w");

            for(j = 0; j < 4; j++)
            {
                fprintf(test2, "something\n");
            }
            fclose(test2);

            exit(0);
        }
        else 
        {    
             int returnStatus;    
             waitpid(childPid, &returnStatus, 0);
        }   

        sleep(2);
    }
    return 0;
}

valgrind结果:

==6314== Memcheck, a memory error detector
==6314== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==6314== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==6314== Command: ./test
==6314== Parent PID: 6313
==6314== 
==6315== 
==6315== HEAP SUMMARY:
==6315==     in use at exit: 0 bytes in 0 blocks
==6315==   total heap usage: 2 allocs, 2 frees, 1,136 bytes allocated
==6315== 
==6315== All heap blocks were freed -- no leaks are possible
==6315== 
==6315== For counts of detected and suppressed errors, rerun with: -v
==6315== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==6317== 
==6317== HEAP SUMMARY:
==6317==     in use at exit: 0 bytes in 0 blocks
==6317==   total heap usage: 3 allocs, 3 frees, 1,704 bytes allocated
==6317== 
==6317== All heap blocks were freed -- no leaks are possible
==6317== 
==6317== For counts of detected and suppressed errors, rerun with: -v
==6317== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==6319== 
==6319== HEAP SUMMARY:
==6319==     in use at exit: 0 bytes in 0 blocks
==6319==   total heap usage: 4 allocs, 4 frees, 2,272 bytes allocated
==6319== 
==6319== All heap blocks were freed -- no leaks are possible
==6319== 
==6319== For counts of detected and suppressed errors, rerun with: -v
==6319== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

1 个答案:

答案 0 :(得分:1)

使用描述here的massif,我们获得有关我们程序的堆使用情况的输出。我像这样使用它

valgrind --tool=massif ./a.out

然后,在massif的输出文件中(每个子进程也有一个),我们可以看到这样的行:

[...]
#-----------
snapshot=3
#-----------
time=115870
mem_heap_B=4648
mem_heap_extra_B=24
mem_stacks_B=0
heap_tree=peak
n2: 4648 (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
 n1: 4096 0x4E9F380: _IO_file_doallocate (filedoalloc.c:101)
  n1: 4096 0x4EAE874: _IO_doallocbuf (genops.c:398)
   n1: 4096 0x4EADA46: _IO_file_overflow@@GLIBC_2.2.5 (fileops.c:828)
    n1: 4096 0x4EAC11B: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1339)
     n1: 4096 0x4EA0A79: fwrite (iofwrite.c:39)
      n0: 4096 0x1088E5: main (in /home/.../a.out)
 n1: 552 0x4E9FF2B: __fopen_internal (iofopen.c:69)
  n0: 552 0x1088C4: main (in /home/.../a.out)
[...]

在这里,我们看到与文件操作相关的各种库函数(fileops.c)为FILE s(此处显示的fwrite)分配内存。

为什么在注释掉test1-part时,分配不会增加?

好吧,如果您注释掉该部分,则删除在每次循环运行中运行的代码部分。剩下的代码仅在子进程中运行,这意味着父进程的总内存分配(和分配计数)保持为0。所有孩子都将进行相同的操作,从而产生相同数量的分配。

通常,标准库中使用的C代码有时需要内存来完成他们需要做的事情。文件功能需要缓冲区空间来存储读/写字节,因为文件在较低级别被读取为磁盘块,等等。

另外,来自fclose的手册页:

  

fclose()函数刷新stream指向的流(使用fflush(3)写入任何缓冲的输出数据)并关闭底层文件描述符。

这里引用了一些缓冲数据,当你调用fclose时也会释放这些缓冲区。