关于内存泄漏的检查网上有很多的例子和代码,其基本的方法都是用宏,替换掉内存分配以及释放的函数。但是现在网上很多的例子中没有一个是适合我们公司的需求的。
具体的对内存泄漏检查有如下要求:
1. 内存泄漏检查的代码尽可能少的占用CPU及内存
2. 尽可能的不影响原程序
因为,我们的服务器程序有泄漏而且是特殊情况下会泄漏,平时很难模拟出来。
对于这种情况下的内存泄漏我以前的做法如下:
1. 用写文件的方法记录所有的内存分配以及释放的操作
2. 再写一个工具去分析所有的记录,从中找出泄漏的代码
这样做需要大量的硬盘空间,不过,这个无所谓了现在硬盘很便宜!
不过需要考虑到服务器程序当中包含了exe以及多个dll,为了通用,内存泄漏检查分为下面几个部分:
1. IMemLeak.h IMemLeak.cpp 加入每一个模块当中
2. MemLeakLog.dll 统一记录所有的内存操作,将其记录到文件当中
3. MemCheckTool.exe 分析工具
//IMemLeak.h
#ifndef _YG_MEMDBG_H_
#define_YG_MEMDBG_H_
#include <cstdlib>
//Redefines
#definemalloc(size) mallocb(size, __FILE__, __LINE__)
#definefree(memblock) freeb(memblock, __FILE__, __LINE__)
#definerealloc(memblock, size) reallocb(memblock, size, __FILE__, __LINE__)
#definecalloc(num, size) callocb(num, size, __FILE__, __LINE__)
//Redefined functions
void* mallocb(size_t size, constchar*pszFile, intnLine);
voidfreeb(void*memblock, constchar*pszFile, intnLine);
void* reallocb(void*memblock, size_t size, constchar*pszFile, intnLine);
void* callocb(size_t num, size_t size, constchar*pszFile, intnLine);
//For C++
void* operatornew(size_t size, constchar*pszFile, intnLine);
void* operatornew[](size_t size, constchar*pszFile, intnLine);
voidoperatordelete(void*pvMem) throw();
voidoperatordelete[](void*pvMem) throw();
voidpre_delete(constchar*pszFile, intnLine);
//Redefine new and delete
#definenewnew(__FILE__, __LINE__)
#definedelete pre_delete(__FILE__, __LINE__),delete
#endif
//IMemLeak.cpp
#include <stdio.h>
#include <tchar.h>
#include <stdlib.h>
#include <malloc.h>
#include <Windows.h>
#include <cstdlib>
enumEOperateType
{
Type_Malloc,
Type_Calloc,
Type_Realloc,
Type_New,
Type_New_Array,
Type_Free,
Type_Delete,
Type_Delete_Array
};
typedef void(__stdcall * pFun_MemLeakLog)(LPCSTR PLog);
pFun_MemLeakLog MemLeakLog = NULL;
voidCheckMemLeakLogDLL()
{
if(MemLeakLog == NULL)
{
HINSTANCE hinstLib = LoadLibrary(_T("MemLeakLog.dll"));
if(hinstLib != NULL)
{
MemLeakLog = (pFun_MemLeakLog)GetProcAddress(hinstLib, "MemLeakLog");
}
}
}
voidLog(EOperateType type, void* pmem, size_t size, intnLine, constchar* pszFile)
{
CheckMemLeakLogDLL();
chartemp[1024];
if(MemLeakLog != NULL)
{
memset(temp, 0, 1024);
sprintf_s(temp, 1024, "%d-%p-%d-%d [%s] ", type, pmem, size, nLine, pszFile);
MemLeakLog(temp);
}
}
void* mallocb(size_t size, constchar*pszFile, intnLine)
{
void* pRet = malloc(size);
Log(Type_Malloc, pRet, size, nLine, pszFile);
returnpRet;
}
void* callocb(size_t num, size_t size, constchar*pszFile, intnLine)
{
void* pRet = calloc(num, size);
Log(Type_Calloc, pRet, size, nLine, pszFile);
returnpRet;
}
voidfreeb(void*memblock, constchar*pszFile, intnLine)
{
if(memblock)
{
Log(Type_Free, memblock, 0, 0, "NULL");
}
free(memblock);
}
void* reallocb(void*memblock, size_t size, constchar*pszFile, intnLine)
{
void* pRet;
pRet = realloc(memblock, size);
Log(Type_Free, memblock, size, nLine, pszFile);
Log(Type_Realloc, pRet, size, nLine, pszFile);
returnpRet;
}
void* operatornew(size_t size, constchar*pszFile, intnLine)
{
void* pRet = malloc(size);
Log(Type_New, pRet, size, nLine, pszFile);
returnpRet;
}
void* operatornew[](size_t size, constchar*pszFile, intnLine)
{
void* pRet = malloc(size);
Log(Type_New_Array, pRet, size, nLine, pszFile);
returnpRet;
}
//#include <new>
voidoperatordelete(void*memblock) throw()
{
if(memblock)
{
Log(Type_Delete, memblock, 0, 0, "NULL");
}
free(memblock);
}
voidoperatordelete[](void*memblock) throw()
{
if(memblock)
{
Log(Type_Delete_Array, memblock, 0, 0, "NULL");
}
free(memblock);
}
voidpre_delete(constchar*pszFile, intnLine)
{
}
- 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.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
- 111.
- 112.
- 113.
- 114.
- 115.
- 116.
- 117.
- 118.
- 119.
- 120.
- 121.
- 122.
- 123.
- 124.
- 125.
- 126.
注意:
a. 输出的目录我是写死了,在D:MemLeak_Log
b. 在被检查工程里面请增加/FC选项。Project->Properties->Configuration->C/C++->Advanced->Use Full Path Yes(/FC)
c. MemLeakLog.dll 拷贝到与被检查内存泄漏的进程所在的目录下面
我附带上一个例子,大家一看就明白了。
下载地址:http://down.51cto.com/data/236002
原文链接:http://www.cnblogs.com/russinovich/archive/2011/08/12/2135625.html
【编辑推荐】