2011年01月17日 星期一 08:56
(3) 内嵌程序
可以重载内存分配和释放函数 new 和 delete,然后编写程序定期统计内存的分配和释放,从中找出可能的内存泄漏。或者调用系统函数定期监视程序堆的大小,关键要确定堆的增长是泄漏而不是合理的内存使用。这类方法比较复杂,在这就不给出详细例子了。
3. 动态运行检测
实时检测工具主要有 valgrind, Rational purify 等。
(1) Valgrind
valgrind 是帮助程序员寻找程序里的 bug 和改进程序性能的工具。程序通过 valgrind 运行时,valgrind 收集各种有用的信息,通过这些信息可以找到程序中潜在的 bug 和性能瓶颈。
Valgrind 现在提供多个工具,其中最重要的是 Memcheck,Cachegrind,Massif 和 Callgrind。Valgrind 是在 Linux 系统下开发应用程序时用于调试内存问题的工具。它尤其擅长发现内存管理的问题,它可以检查程序运行时的内存泄漏问题。其中的 memecheck 工具可以用来寻找 c、c++ 程序中内存管理的错误。可以检查出下列几种内存操作上的错误:
读写已经释放的内存
读写内存块越界(从前或者从后)
使用还未初始化的变量
将无意义的参数传递给系统调用
内存泄漏
(2) Rational purify
Rational Purify 主要针对软件开发过程中难于发现的内存错误、运行时错误。在软件开发过程中自动地发现错误,准确地定位错误,提供完备的错误信息,从而减少了调试时间。同时也是市场上唯一支持多种平台的类似工具,并且可以和很多主流开发工具集成。Purify 可以检查应用的每一个模块,甚至可以查出复杂的多线程或进程应用中的错误。另外不仅可以检查 C/C++,还可以对 Java 或 .NET 中的内存泄漏问题给出报告。
在 Linux 系统中,使用 Purify 需要重新编译程序。通常的做法是修改 Makefile 中的编译器变量。下面是用来编译本文中程序的 Makefile:
CC=purify gcc
首先运行 Purify 安装目录下的 purifyplus_setup.sh 来设置环境变量,然后运行 make 重新编译程序。
./purifyplus_setup.sh
下面给出编译一个代码文件的示例,源代码文件命名为 test3.cpp. 用 purify 和 g++ 的编译命令如下,‘-g’是编译时加上调试信息。
purify g++ -g test3.cpp –o test
运行编译生成的可执行文件 test,就可以得到图1,可以定位出内存泄漏的具体位置。
./test
清单3. Purify 分析的代码
- #include
- char * Logmsg;
- int LeakTest(char * Para)
- {
- if( NULL ==Para){
- //local_log("LeakTest Func: empty parameter\n");
- return -1;
- }
- Logmsg = new char[128];
- for (int i = 0 ; i < 128 ; i++)
- Logmsg[i] = i%64;
- if( NULL == Logmsg){
- //local_log("memeory allocation failed\n");
- return -2;
- }
- sprintf(Logmsg,"LeakTest routine exit: '%s'.\n", Para);
- //local_log(Logmsg);
- return 0;
- }
- int main(int argc,char **argv )
- {
- char szInit [] = "testcase1";
- int i;
- LeakTest(szInit);
- for ( i = 0 ; i < 2 ; i++){
- if(i% 200 == 0)
- LeakTest(szInit);
- sleep(1);
- }
- return 0;
- }
需要指出的是,程序必须编译成调试版本才可以定位到具体哪行代码发生了内存泄漏。即在 gcc 或者 g++ 中,必须使用 "-g" 选项。
图 1 purify 的输出结果
以上就是几种内存泄露,以及调试方法。对程序内存泄露的问题有着一定的帮助。
Zeuux © 2024
京ICP备05028076号