内存泄漏检查

关于内存泄漏的检查网上有很多的例子和代码,其基本的方法都是用宏,替换掉内存分配以及释放的函数。但是现在网上很多的例子中没有一个是适合我们公司的需求的。

具体的对内存泄漏检查有如下要求:

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
#define malloc(size) mallocb(size, __FILE__, __LINE__)
#define free(memblock) freeb(memblock, __FILE__, __LINE__)
#define realloc(memblock, size) reallocb(memblock, size, __FILE__, __LINE__)
#define calloc(num, size) callocb(num, size, __FILE__, __LINE__)

//Redefined functions
void * mallocb(size_t size, const char *pszFile, int nLine);
void freeb(void *memblock, const char *pszFile, int nLine);
void * reallocb(void *memblock, size_t size, const char *pszFile, int nLine);
void * callocb(size_t num, size_t size, const char *pszFile, int nLine);

//For C++
void * operator new(size_t size, const char *pszFile, int nLine);
void * operator new[](size_t size, const char *pszFile, int nLine);

void operator delete(void *pvMem) throw();
void operator delete[](void *pvMem) throw();

void pre_delete(const char *pszFile, int nLine);

//Redefine new and delete
#define new     new(__FILE__, __LINE__)
#define delete    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>

enum EOperateType
{
    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;

void CheckMemLeakLogDLL()
{
    if (MemLeakLog == NULL)
    {
        HINSTANCE  hinstLib = LoadLibrary(_T("MemLeakLog.dll"));
        if (hinstLib != NULL)
        {
            MemLeakLog = (pFun_MemLeakLog)GetProcAddress(hinstLib, "MemLeakLog");
        }
    }
}

void Log(EOperateType type, void * pmem, size_t size, int nLine, const char* pszFile)
{
    CheckMemLeakLogDLL();

    char temp[1024];
    if (MemLeakLog != NULL)
    {
        memset(temp, 0, 1024);
        sprintf_s(temp, 1024, "%d-%p-%d-%d [%s]n", type, pmem, size, nLine, pszFile);
        MemLeakLog(temp);
    }
}

void * mallocb(size_t size, const char *pszFile, int nLine)
{
    void * pRet = malloc(size);
    Log(Type_Malloc, pRet, size, nLine, pszFile);
    return pRet;
}

void * callocb(size_t num, size_t size, const char *pszFile, int nLine)
{
    void * pRet = calloc(num, size);
    Log(Type_Calloc, pRet, size, nLine, pszFile);
    return pRet;
}

void freeb(void *memblock, const char *pszFile, int nLine)
{
    if (memblock)
    {
        Log(Type_Free, memblock, 0, 0, "NULL");
    }

    free(memblock);
}

void * reallocb(void *memblock, size_t size, const char *pszFile, int nLine)
{
    void * pRet;
    pRet = realloc(memblock, size);

    Log(Type_Free,    memblock, size, nLine, pszFile);
    Log(Type_Realloc, pRet, size, nLine, pszFile);
    return pRet;
}

void * operator new(size_t size, const char *pszFile, int nLine)
{
    void * pRet = malloc(size);

    Log(Type_New, pRet, size, nLine, pszFile);
    return pRet;
}

void * operator new[](size_t size, const char *pszFile, int nLine)
{
    void * pRet = malloc(size);

    Log(Type_New_Array, pRet, size, nLine, pszFile);
    return pRet;
}

//#include <new>

void operator delete(void *memblock) throw ()
{
    if (memblock)
    {
        Log(Type_Delete, memblock, 0, 0, "NULL");
    }

    free(memblock);
}

void operator delete[](void *memblock) throw()
{
    if (memblock)
    {
        Log(Type_Delete_Array, memblock, 0, 0, "NULL");
    }

    free(memblock);
}

void pre_delete(const char *pszFile, int nLine)
{

}

MEM_1

MEM_2

注意:

a. 输出的目录我是写死了,在D:MemLeak_Log

b. 在被检查工程里面请增加/FC选项。Project->Properties->Configuration->C/C++->Advanced->Use Full Path Yes(/FC)

c. MemLeakLog.dll 拷贝到与被检查内存泄漏的进程所在的目录下面

我附带上一个例子,大家一看就明白了。

下载地址
原文链接: https://www.cnblogs.com/russinovich/archive/2011/08/12/2135625.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/30423

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月8日 上午7:45
下一篇 2023年2月8日 上午7:45

相关推荐