Memory Leak和Valgrind

首先必须搞懂什么才是Memory Leak?其实业界一直有两种定义。

a. 大众化说法:一块内存由new或者malloc分配了,在程序结束前一直没有被回收。但程序始终有指针指向这块内存。

b. 更严格的说法:一块内存由new或者malloc分配在堆上面,在程序结束前,已经没有任何指针能够指向这块内存了。

对于第一种Memory Leak,其实危害不大,因为一旦进程结束了,所有该进程分配的内存(包括Leak掉的内存)都会被kernel回收。对于第二种Memory Leak,大家一致认为对大型服务器端运行的程序是有危害的。如果程序一直在执行,Leak的内存会越来越多,可能会耗尽程序的堆内存。

相应的,在Valgrind里面,称第一种Leak为“still reachable”,称第二种为“memory leak”。对于memory leak又分为两种。Directly lost和Indirectly lost。

image

上图中的BBB在case (1),(2)情况下是Still reachable。Case (3)是Directly lost,而Case(4)是Indirectly lost。用一个例子能够很清楚的说明问题。

  
  
  
  
  1. #include <stdlib.h>  
  2. #include <string.h>  
  3.  
  4. void **rrr;  
  5. int main(void)  
  6. {  
  7.     /* Allocation of AAA block, start-pointer in RRR */ 
  8.     rrr = malloc(sizeof(void *));  
  9.  
  10.     /* Allocation of BBB block, start-pointer in AAA */ 
  11.     *rrr = strdup("bbb");  
  12.  
  13.     /* oops, we lost the start-pointer to AAA */ 
  14.     rrr = NULL;  
  15.     return 0;  

用Valgrind检查上面的代码:

  
  
  
  
  1. $ valgrind --leak-check=full --show-reachable=yes ./a.out  
  2. ==16420== 4 bytes in 1 blocks are indirectly lost in loss record 1 of 2  
  3. ==16420== at 0x4A05E1C: malloc (vg_replace_malloc.c:195)  
  4. ==16420== by 0x374EA79771: strdup (in /lib64/libc-2.5.so)  
  5. ==16420== by 0x4005E2: main (in /home/zzhan17/test/a.out)  
  6. ==16420==  
  7. ==16420== 12 (8 direct, 4 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 2  
  8. ==16420== at 0x4A05E1C: malloc (vg_replace_malloc.c:195)  
  9. ==16420== by 0x4005CA: main (in /home/zzhan17/test/a.out)  
  10. ==16420==  
  11. ==16420== LEAK SUMMARY:  
  12. ==16420== definitely lost: 8 bytes in 1 blocks  
  13. ==16420== indirectly lost: 4 bytes in 1 blocks  
  14. ==16420== possibly lost: 0 bytes in 0 blocks  
  15. ==16420== still reachable: 0 bytes in 0 blocks  
  16. ==16420== suppressed: 0 bytes in 0 blocks 

如果把上面的“rrr = NULL; ”代码删除, Valgrind不会报告任何memory leak但会显示有memory still reachable,原因是void **rrr是global pointer,程序退出时rrr还能指向AAA和BBB。

image

因此,最为重要的是分析Definitely lost和Indirect lost,也就是以上的Case 3, 4和9。所谓的Interior lost是指向block内的指针,也就是我们常说的野指针。所以很多Possible lost并不是真正的Memory leak。

以后有空的话还会给大家介绍Valgrind的其他模块,如Callgrind,CacheGrind,还有图形化的工具KCacheGrind。这些对Performance Tuning都很有帮助。

你可能感兴趣的:(内存泄漏,休闲,valgrind,INDIRECT,lost,lost,Definitely)