linux内存泄露
① 嵌入式linux怎么检内存泄漏雨
1. 在需要内存泄漏检查的代码的开始调用void mtrace(void) (在mcheck.h中? 有声明). mtrace为malloc等函数安装hook, 用于记录内存分配信息.在需要内存泄漏检查的代码的结束调用void muntrace(void).
注意: 一般情况下不要调用muntrace, 而让程序自然结束. 因为可能有些释放内存代码要到muntrace之后才运行.
2. 用debug模式编译被检查代码(-g或-ggdb)
3. 设置环境变量MALLOC_TRACE为一文件名, 这一文件将存有内存分配信息.
4. 运行被检查程序, 直至结束或muntrace被调用.
5. 用mtrace命令解析内存分配Log文件($MALLOC_TRACE)
(mtrace foo $MALLOC_TRACE, where foo is the executible name)
如果有内存泄漏, mtrace会输出分配泄漏
内存的代码位置,以及分配数量.
附加说明
1. 可以将mtrace, muntrace放入信号处理函数(USR1, USR2), 以动态地进行内存泄漏检查控制.
2. mtrace是个perl代码, 如果你对符号地址与代码文本的转换感兴趣, 可以读一下.
3. again, 尽量不要用muntrace()
For C++ Leak:
检查内存泄漏的方法除glibc提供外;还可以试试一些专用的程序。
很奇怪,redhat 9 居然不带mtrace perl脚本,只好下载gcc源码编译了
wget --passive-ftp ftp://rpmfind.net/linux/redhat/9 ... -2.3.2-11.9.src.rpm
rpm -ivh glibc*.src.rpm
cd /usr/src/redhat/SPECS/
rpmbuild -ba glibc-9.spec
cd /var/tmp/glibc-2.3.2-root/usr/bin/
cp mtrace /usr/bin/
调试方法如下:
vi a.c
1 #include
2
3 int main()
4 {
5 mtrace();
6 malloc(10);
7 malloc(16);
8 return 0;
9 }
$gcc -g a.c #记得编译带-g调试选项
$export MALLOC_TRACE=a.log
$./a.out
$unset MALLOC_TRACE #记得执行完后unset变量,否则可能运行其他命令可能覆盖log
$mtrace a.out a.log
Memory not freed:
-----------------
Address Size Caller
0x09b08378 0xa at /XXX/a.c:6
0x09b08388 0x10 at /XXX/a.c:7
可以看到,会显示未释放动态空间的代码具体位置。
② linux内存泄漏怎么查
可以使用对应的软件测试工具来查,如parasoft的c/c++等
③ 怎么样来检查Linux系统下内存泄漏
内存泄漏是指程序动态申请的内存在使用完后没有释放,导致这段内存不能被操作系统回收再利用。 例如这段程序,申请了4个字节的空间但没有释放,有4个字节的内存泄漏。
#include <iostream>using namespace std;int main()
{ int *p = new int(1); cout <<*p<<endl; return 0}
1
2
3
4
5
6
7
8
9
随着时间的推移,泄漏的内存越来越多,可用的内存越来越少,轻则性能受损,重则系统崩溃。
一般情况下,发生内存泄漏时,重启就可以回收泄漏的内存。但是对于Linux,通常跑的是服务器程序,不可以随意重启,在内存泄漏问题上就要格外小心。
内存泄漏特点
难复现 — 要运行到足够长的时间才会暴露。
难定位 — 出错位置是随机的,看不出与内存泄漏的代码有什么联系。
最简单的方法
为了避免写出内存泄漏的程序,通常会有这样的编程规范,要求我们在写程序时申请和释放成对出现的。因为每一次申请都意味着必须有一次释放与它相对应。
基于这个特点,一种简单的方法就是在代码中统计申请和释放的次数,如果申请和释放的数量不同,就认为是内存泄漏了。
#include "stdio.h"#include "stdlib.h"int malloc_count, free_count;void * my_malloc(int size)
{
malloc_count++; return malloc(size);
}void my_free(void *p)
{
free_count++; free(p);
}int main()
{
count = 0; int *p1 = (int *)my_malloc(sizeif(int)) int *p2 = (int *)my_malloc(sizeif(int)) printf("%d, %d", p1, p2);
my_free(p1); if(malloc_count != free_count) printf("memory leak!\n"); return 0}
④ 如何定位分析linux内存泄漏问题
1、阅读源代码及分析动态内存的使用
由于之前没有做过类似的问题(纯属小白了,惨遭鄙视....),所以就想着通过自己去看代码,查找里面涉及到使用动态内存的代码段去定位问题(现在想想,真是太幼稚了,大家见笑了...),但是自己还是去通过对源代码跟踪、分析,主要是对动态分配的内存(如malloc函数分配的内存)、一些文件描述符等进行跟踪,分析在程序逻辑中对动态分配的内存有没有手动进行释放,打开的文件描述符有没有关闭等这些代码一点点的去分析,当然这也是熟悉代码,了解的一个过程。
2、利用memwatch内存检测工具对程序进行内存分析
Memwatch是一款C语言的内存检测工具。memwatch使用它自己定义的功能函数取代所有在你的程序中用ANSI C定义的内存分配函数,memwatch的内存分配函数包含了所有的分配记录信息。memwatch功能默认不是开启的,除非定义了MEMWATCH,否则在代码中不会跟踪相关的内存使用情况。memwatch通常将它的数据写入到memwatch.log文件中,它也可以被重定向.更多Linux操作知识,可以网络《Linux就该这么学》。
⑤ 如何在linux操作系统下检测内存泄漏
内存泄漏是指程序动态申请的内存在使用完后没有释放,导致这段内存不能被操作系统回收再利用。
例如这段程序,申请了4个字节的空间但没有释放,有4个字节的内存泄漏。
{ int *p = new int(1); cout <<*p<<endl; return 0}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
随着时间的推移,泄漏的内存越来越多,可用的内存越来越少,轻则性能受损,重则系统崩溃。
一般情况下,发生内存泄漏时,重启就可以回收泄漏的内存。但是对于Linux,通常跑的是服务器程序,不可以随意重启,在内存泄漏问题上就要格外小心。
内存泄漏特点难复现 — 要运行到足够长的时间才会暴露。
难定位 — 出错位置是随机的,看不出与内存泄漏的代码有什么联系。
为了避免写出内存泄漏的程序,通常会有这样的编程规范,要求我们在写程序时申请和释放成对出现的。因为每一次申请都意味着必须有一次释放与它相对应。
基于这个特点,一种简单的方法就是在代码中统计申请和释放的次数,如果申请和释放的数量不同,就认为是内存泄漏了。
#include "stdio.h"#include "stdlib.h"int malloc_count, free_count;void * my_malloc(int size){
malloc_count++; return malloc(size);
}void my_free(void *p)
{
free_count++; free(p);
}int main()
{
count = 0; int *p1 = (int *)my_malloc(sizeif(int)) int *p2 = (int *)my_malloc(sizeif(int)) printf("%d, %d", p1, p2);
my_free(p1); if(malloc_count != free_count) printf("memory leak! "); return 0}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 优点:
直观,容易理解,容易实现
- 缺点:
1.该方法要求运行结束时对运行中产生的打印分析才能知道结果。
2.该方法要求封装所有申请和释放空间的函数,并在调用的地方修改成调用封装后的函数。虽然C中申请/释放内存接口并不多,但是对于一个大型的项目,调用这些接口的地方却是很多的,要全部替换是一个比较大的工作量。
3.只对C语言适用,不能应用于C++
4.对于所调用的库不适用。如果希望应用于库,则要修改库代码
5.只能检测是否泄漏,却没有具体信息,比如泄漏了多少空间
6.不能说明是哪一行代码引起了泄漏
改进这种方法虽然简单的,却有许多的不足,无法真正应用于项目中。欲知怎样改进,且看下回分解。
⑥ linux内存泄漏如何定位
1、阅读源代码及分析动态内存的使用 由于之前没有做过类似的问题(纯属小白了,惨遭鄙视.),所以就想着通过自己去看代码,查找...
2、利用memwatch内存检测工具对程序进行内存分析Memwatch是一款C语言的内存检测工具。memwatch使用它自己定义的功能函数取代所有在你的程...
⑦ linux中检查内存泄漏的工具有哪些
Valgrind 是一款 Linux下(支持 x86、x86_64和ppc32)程序的内存调试工具,它可以对编译后的二进制程序进行内存使用监测(C语言中的malloc和free,以及C++中的new和delete),找出内存泄漏问题。
⑧ 如何在Linux操作系统下检测内存泄漏
Linux操作系统应用专区1.开发背景:
在 Windows 下使用 VC 编程时,我们通常需要 DEBUG 模式下运行程序,而后调试器将在退出程序时,打印出程序运行过程中在堆上分配而没有释放的内存信息,其中包括代码文件名、行号以及内存大小。该功能是 MFC Framework 提供的内置机制,封装在其类结构体系内部。
在 Linux 或者 Unix 下,我们的 C++ 程序缺乏相应的手段来检测内存信息,而只能使用 top 指令观察进程的动态内存总额。而且程序退出时,我们无法获知任何内存泄漏信息。为了更好的辅助在 linux 下程序开发,我们在我们的类库项目中设计并实现了一个内存检测子系统。下文将简述 C++ 中的 new 和 delete 的基本原理,并讲述了内存检测子系统的实现原理、实现中的技巧,并对内存泄漏检测的高级话题进行了讨论。2.New和delete的原理
当我们在程序中写下 new 和 delete 时,我们实际上调用的是 C++ 语言内置的 new operator 和 delete operator。所谓语言内置就是说我们不能更改其含义,它的功能总是一致的。以 new operator 为例,它总是先分配足够的内存,而后再调用相应的类型的构造函数初始化该内存。而 delete operator 总是先调用该类型的析构函数,而后释放内存(图1)。我们能够施加影响力的事实上就是 new operator 和 delete operator 执行过程中分配和释放内存的方法。
new operator 为分配内存所调用的函数名字是 operator new,其通常的形式是 void * operator new(size_t size); 其返回值类型是 void*,因为这个函数返回一个未经处理(raw)的指针,未初始化的内存。参数 size 确定分配多少内存,你能增加额外的参数重载函数 operator new,但是第一个参数类型必须是 size_t。
delete operator 为释放内存所调用的函数名字是 operator delete,其通常的形式是 void operator delete(void *memoryToBeDeallocated);它释放传入的参数所指向的一片内存区。
这里有一个问题,就是当我们调用 new operator 分配内存时,有一个 size 参数表明需要分配多大的内存。但是当调用 delete operator 时,却没有类似的参数,那么 delete operator 如何能够知道需要释放该指针指向的内存块的大小呢?答案是:对于系统自有的数据类型,语言本身就能区分内存块的大小,而对于自定义数据类型(如我们自定义的类),则 operator new 和 operator delete 之间需要互相传递信息。
当我们使用 operator new 为一个自定义类型对象分配内存时,实际上我们得到的内存要比实际对象的内存大一些,这些内存除了要存储对象数据外,还需要记录这片内存的大小,此方法称为 cookie。这一点上的实现依据不同的编译器不同。(例如 MFC 选择在所分配内存的头部存储对象实际数据,而后面的部分存储边界标志和内存大小信息。g++ 则采用在所分配内存的头 4 个自己存储相关信息,而后面的内存存储对象实际数据。)当我们使用 delete operator 进行内存释放操作时,delete operator 就可以根据这些信息正确的释放指针所指向的内存块。
以上论述的是对于单个对象的内存分配/释放,当我们为数组分配/释放内存时,虽然我们仍然使用 new operator 和 delete operator,但是其内部行为却有不同:new operator 调用了operator new 的数组版的兄弟- operator new[],而后针对每一个数组成员调用构造函数。而 delete operator 先对每一个数组成员调用析构函数,而后调用 operator delete[] 来释放内存。需要注意的是,当我们创建或释放由自定义数据类型所构成的数组时,编译器为了能够标识出在 operator delete[] 中所需释放的内存块的大小,也使用了编译器相关的 cookie 技术。
⑨ 如何在linux下检测内存泄漏
linux操作系统应用专区
1.开发背景:
在
windows
下使用
vc
编程时,我们通常需要
debug
模式下运行程序,而后调试器将在退出程序时,打印出程序运行过程中在堆上分配而没有释放的内存信息,其中包括代码文件名、行号以及内存大小。该功能是
mfc
framework
提供的内置机制,封装在其类结构体系内部。
在
linux
或者
unix
下,我们的
c++
程序缺乏相应的手段来检测内存信息,而只能使用
top
指令观察进程的动态内存总额。而且程序退出时,我们无法获知任何内存泄漏信息。为了更好的辅助在
linux
下程序开发,我们在我们的类库项目中设计并实现了一个内存检测子系统。下文将简述
c++
中的
new
和
delete
的基本原理,并讲述了内存检测子系统的实现原理、实现中的技巧,并对内存泄漏检测的高级话题进行了讨论。
2.new和delete的原理
当我们在程序中写下
new
和
delete
时,我们实际上调用的是
c++
语言内置的
new
operator
和
delete
operator。所谓语言内置就是说我们不能更改其含义,它的功能总是一致的。以
new
operator
为例,它总是先分配足够的内存,而后再调用相应的类型的构造函数初始化该内存。而
delete
operator
总是先调用该类型的析构函数,而后释放内存(图1)。我们能够施加影响力的事实上就是
new
operator
和
delete
operator
执行过程中分配和释放内存的方法。
new
operator
为分配内存所调用的函数名字是
operator
new,其通常的形式是
void
*
operator
new(size_t
size);
其返回值类型是
void*,因为这个函数返回一个未经处理(raw)的指针,未初始化的内存。参数
size
确定分配多少内存,你能增加额外的参数重载函数
operator
new,但是第一个参数类型必须是
size_t。
delete
operator
为释放内存所调用的函数名字是
operator
delete,其通常的形式是
void
operator
delete(void
*memorytobedeallocated);它释放传入的参数所指向的一片内存区。
这里有一个问题,就是当我们调用
new
operator
分配内存时,有一个
size
参数表明需要分配多大的内存。但是当调用
delete
operator
时,却没有类似的参数,那么
delete
operator
如何能够知道需要释放该指针指向的内存块的大小呢?答案是:对于系统自有的数据类型,语言本身就能区分内存块的大小,而对于自定义数据类型(如我们自定义的类),则
operator
new
和
operator
delete
之间需要互相传递信息。
当我们使用
operator
new
为一个自定义类型对象分配内存时,实际上我们得到的内存要比实际对象的内存大一些,这些内存除了要存储对象数据外,还需要记录这片内存的大小,此方法称为
cookie。这一点上的实现依据不同的编译器不同。(例如
mfc
选择在所分配内存的头部存储对象实际数据,而后面的部分存储边界标志和内存大小信息。g++
则采用在所分配内存的头
4
个自己存储相关信息,而后面的内存存储对象实际数据。)当我们使用
delete
operator
进行内存释放操作时,delete
operator
就可以根据这些信息正确的释放指针所指向的内存块。
以上论述的是对于单个对象的内存分配/释放,当我们为数组分配/释放内存时,虽然我们仍然使用
new
operator
和
delete
operator,但是其内部行为却有不同:new
operator
调用了operator
new
的数组版的兄弟-
operator
new[],而后针对每一个数组成员调用构造函数。而
delete
operator
先对每一个数组成员调用析构函数,而后调用
operator
delete[]
来释放内存。需要注意的是,当我们创建或释放由自定义数据类型所构成的数组时,编译器为了能够标识出在
operator
delete[]
中所需释放的内存块的大小,也使用了编译器相关的
cookie
技术。
⑩ linux c 内存泄漏问题
具体来说,myfree中的num变量在内存中紧邻着p变量,如果你将num申明为int,那他只占四个字节,而你初始化num的时候 memcpy(&num, p, sizeof(size_t)); 却会将8个字节拷进去,这会修改紧邻这num的变量p,直接导致p被清零(如果malloc free外加修改的话,清的不一定是0),而free函数在传入空指针是不做处理的。我把代码修改了一下,你可以看一下下面程序的输出,对应myfree的free那一行,实际被free的是空指针。
#include<stdio.h>
#include<malloc.h>
#include<pthread.h>
#include<unistd.h>
intfCnt=0,mCnt=0;
pthread_mutex_tmutex;
void*mynew(size_tsz){
void*p=malloc(sizeof(size_t)+sz);
memcpy(p,&sz,sizeof(size_t));
pthread_mutex_lock(&mutex);
mCnt+=sz+sizeof(size_t);
printf("mallocsz[%d],mCnt[%d],fCnt[%d] ",sz+sizeof(size_t),mCnt,
fCnt);
pthread_mutex_unlock(&mutex);
returnp+sizeof(size_t);
}
voidmyfree(void*prt){
void*p=prt-sizeof(size_t);
if(p==NULL){
printf("pbufisNULL ");
return;
}
intnum=0;//error!
//size_tnum=0;
printf("%p,%p ",&p,&num);
memcpy(&num,p,sizeof(size_t));
pthread_mutex_lock(&mutex);
fCnt+=num+sizeof(size_t);
printf("freesz[%d],fCnt[%d],mCnt[%d] ",num,fCnt,mCnt);
pthread_mutex_unlock(&mutex);
printf("trytofree%p ",p);
free(p);
}
intmain(){
void*p=mynew(100);
printf("pis%p ",p);
myfree(p);
usleep(1000000);
return0;
}