内存泄露


  程序退出后,malloc的内存会不会自动free呢?要回答这个问题,我们先要熟悉进程空间的内存相关结构.


一般编程主要只涉及进程的堆空间和栈空间(当然进程还有其他的,但初学可以不考虑).

栈空间的内存是给函数内的局部变量(包括函数参数)用的,通过函数调用和函数返回自动得分配释放(实际上只是调整栈顶指针的位置)。因为这是个“自动”的过程,所以有个额外的“栈空间溢出”的问题,主要的就是函数内局部变量不宜过大(比如int array[100*1024*1024],申请100M的内存),递归调用不要嵌套过多。

堆空间的内存简单的说就是通过malloc/new申请的,你可以选择在不再使用时释放(用free/delete),但不是必须这么做——程序退出时系统会自动回收该进程所占用的内存(僵尸进程有一点例外--它要保存进程的返回值,直到被取走才释放)。不释放内存只有两个害处:一是本进程达到能申请内存的最大值然后申请失败,导致本进程无法继续正常运行;二是本进程占用内存过多,影响系统的其他进程,或者是提高本程序运行的硬件要求。

下面的这个小例子,就是验证一下进程退出后会不会自动释放malloc的内存:

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>

void fun( int i);
int *p;
void fun( int i)
{
    p = malloc(sizeof(int));
    *= i;
    printf("malloc successful,and %d has been store to the memory!\n",i);
    printf("malloc the address is %x\n",p);
    exit (0);
}

int main(void)
{
    pid_t pid;
    int k;
    int status;
    k = fork();
    if ( k == 0)
    {
        fun(1);
    }
    else {
        sleep(1);
        printf("------\n");
        pid = wait(&status);
        printf("%x\n",p);
        printf("%d\n",*p);
        return 0;
    }
}



$ ./a.out 
malloc successful,and 1 has been store to the memory!
malloc the address is 804a008
------
0

Segmentation fault


看来进程退出后,malloc的内存也随之由系统自动释放了.

大多数情况下,程序浪费“有限”的内存是关系不大的。但如果某函数每被调用一次就浪费一点内存(即申请了内存,不再使用,却不释放),随着函数被调用次数的增多,浪费的内存趋于“无限”,就会产生严重的问题,即所谓“内存泄露”。“内存泄露”的存在有两个必要条件,一是程序在持续的“浪费”内存,二是程序没有退出。所以,如果能保证程序在正常退出前浪费的内存不超过某一阈值,就可以不考虑释放内存(这也就是我们写小测试程序的情况)。

以上是内存申请了可以不释放的情况,其他情况下(比如程序需要持久运行,这也是实际中最常见的情况),申请的内存都需要释放。下面再说什么时候要申请(malloc/new)内存:
需要申请(malloc/new)内存是出于这样一种需要:栈空间是线程相关的(即栈空间的内存属于某一固定的线程),而我们有时需要线程无关即多个线程共享的内存(换个角度说,对于单线程程序,完全可以只用栈空间完成一切任务,即不用申请内存,只需把函数退出后仍需保留的变量声明在函数外面,代价就是函数参数个数的增多)。事实上,多线程比之单进程,唯一的进步也就是方便了对线程无关内存的访问,也就是可以让堆空间像多进程编程中的共享内存一样使用。

堆空间和栈空间两者之和虽然受到32位进程4G地址空间的限制,但两者之和却可相互调整:比如线程很多时可能需要增大栈空间减小堆空间,线程共享空间需求很大时则反之。

当然,c/c++有很多内存泄漏检测工具,
内存泄漏检测工具:

1.ccmalloc-Linux和Solaris下对C和C++程序的简单的使用内存泄漏和malloc调试库。
2.Dmalloc-Debug Malloc Library.
3.Electric Fence-Linux分发版中由Bruce Perens编写的malloc()调试库。
4.Leaky-Linux下检测内存泄漏的程序。
5.LeakTracer-Linux、Solaris和HP-UX下跟踪和分析C++程序中的内存泄漏。
6.MEMWATCH-由Johan Lindh编写,是一个开放源代码C语言内存错误检测工具,主要是通过gcc的precessor来进行。
7.Valgrind-Debugging and profiling Linux programs, aiming at programs written in C and C++.
8.KCachegrind-A visualization tool for the profiling data generated by Cachegrind and Calltree.
9.IBM Rational PurifyPlus-帮助开发人员查明C/C++、托管.NET、Java和VB6代码中的性能和可靠性错误。PurifyPlus 将内存错误和泄漏检测、应用程序性能描述、代码覆盖分析等功能组合在一个单一、完整的工具包中。
10.Parasoft Insure++-针对C/C++应用的运行时错误自动检测工具,它能够自动监测C/C++程序,发现其中存在着的内存破坏、内存泄漏、指针错误和I/O 等错误。并通过使用一系列独特的技术(SCI技术和变异测试等),彻底的检查和测试我们的代码,精确定位错误的准确位置并给出详细的诊断信息。能作为 Microsoft Visual C++的一个插件运行。
11.Compuware DevPartner for Visual C++ BoundsChecker Suite-为C++开发者设计的运行错误检测和调试工具软件。作为Microsoft Visual Studio和C++ 6.0的一个插件运行。
12.Electric Software GlowCode-包括内存泄漏检查,code profiler,函数调用跟踪等功能。给C++和.Net开发者提供完整的错误诊断,和运行时性能分析工具包。
13.Compuware DevPartner Java Edition-包含Java内存检测,代码覆盖率测试,代码性能测试,线程死锁,分布式应用等几大功能模块。
14.Quest JProbe-分析Java的内存泄漏。
15.ej-technologies JProfiler-一个全功能的Java剖析工具,专用于分析J2SE和J2EE应用程序。它把CPU、执行绪和内存的剖析组合在一个强大的应用中。 JProfiler可提供许多IDE整合和应用服务器整合用途。JProfiler直觉式的GUI让你可以找到效能瓶颈、抓出内存泄漏、并解决执行绪的问题。4.3.2注册码:A-G666#76114F-1olm9mv1i5uuly#0126
16.BEA JRockit-用来诊断Java内存泄漏并指出根本原因,专门针对Intel平台并得到优化,能在Intel硬件上获得最高的性能。


比如valgrind就是在Linux下查找内存泄漏和无效内存访问.具体可以参考下文:
在Linux下使用用Valgrind查找内存泄漏和无效内存访问 http://www.linuxidc.com/Linux/2009-02/18646.htm

还有memwatch,可以参考下文
内存调试--MEMWATCH http://blog.csdn.net/lengxingfei/archive/2006/08/09/1040800.aspx 

当然,你也可以自己封装自己的malloc/free来实现内存的检测

实用小代码之内存泄漏检测  http://blog.chinaunix.net/u/18677/showart_473613.html
实用小代码之内存泄漏检测(二) http://blog.chinaunix.net/u/18677/showart_547975.html 


reference:

内存泄漏(资料搜集)http://blog.chinaunix.net/u2/78225/showart_1844866.html
啥时需要申请内存和释放内存?http://blog.chinaunix.net/u1/47120/showart_372045.html
阅读更多
个人分类: 个人
想对作者说点什么? 我来说一句

vld1.0内存泄漏检测

2009年12月16日 773KB 下载

检查内存泄露 检查内存泄露

2010年05月29日 22KB 下载

linux 内核 内存泄露检测

2011年09月11日 18KB 下载

linux 内核 内存泄露检测 2

2011年09月11日 14KB 下载

Flex内存泄露问题

2011年05月23日 14KB 下载

JVM内存泄露

2011年10月28日 144KB 下载

内存泄露检测工具

2017年12月02日 957KB 下载

TestCxImage

2014年08月06日 23.39MB 下载

ExtJS 内存泄露补丁

2009年10月11日 562KB 下载

没有更多推荐了,返回首页

不良信息举报

内存泄露

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭