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。用一个例子能够很清楚的说明问题。

#include 
#include <string.h>

void **rrr;
int main(void)
{
    /* Allocation of AAA block, start-pointer in RRR */
    rrr = malloc(sizeof(void *));

    /* Allocation of BBB block, start-pointer in AAA */
    *rrr = strdup("bbb");

    /* oops, we lost the start-pointer to AAA */
    rrr = NULL;
    return 0;
}
用Valgrind检查上面的代码:
$ valgrind --leak-check=full --show-reachable=yes ./a.out

==16420== 4 bytes in 1 blocks are indirectly lost in loss record 1 of 2

==16420== at 0x4A05E1C: malloc (vg_replace_malloc.c:195)

==16420== by 0x374EA79771: strdup (in /lib64/libc-2.5.so)

==16420== by 0x4005E2: main (in /home/zzhan17/test/a.out)

==16420==

==16420== 12 (8 direct, 4 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 2

==16420== at 0x4A05E1C: malloc (vg_replace_malloc.c:195)

==16420== by 0x4005CA: main (in /home/zzhan17/test/a.out)

==16420==

==16420== LEAK SUMMARY:

==16420== definitely lost: 8 bytes in 1 blocks

==16420== indirectly lost: 4 bytes in 1 blocks

==16420== possibly lost: 0 bytes in 0 blocks

==16420== still reachable: 0 bytes in 0 blocks

==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和Indirectly lost,也就是以上的Case 3, 4和9。所谓的Interior lost是指向block内的指针,也就是我们常说的野指针。所以很多Possible lost并不是真正的Memory leak。

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

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值