C++内存泄露检查的5个方法

分享到:

一、前言

在Linux平台上 有valgrind可以非常方便的帮助我们定位内存泄漏,因为Linux在开发领域的使用场景大多是跑服务器,再加上它的开源属性,相对而言,处理问题容 易形成“统一”的标准。而在Windows平台,服务器和客户端开发人员惯用的调试方法有很大不同。下面结合我的实际经验,整理下常见定位内存泄漏的方 法。

注意:我们的分析前提是Release版本,因为在Debug环境下,通过VLD这个库或者CRT库本身的内存泄漏检测函数能够分析出内存泄漏,相对而言比较简单。而服务器有很多问题需要在线上并发压力情况下才出现,因此讨论Debug版调试方法意义不大。

二、对象计数

方法:在对象构造时计数++,析构时–,每隔一段时间打印对象的数量

优点:没有性能开销,几乎不占用额外内存。定位结果精确。

缺点:侵入式方法,需修改现有代码,而且对于第三方库、STL容器、脚本泄漏等因无法修改代码而无法定位。

三、重载new和delete

方法:重载new/delete,记录分配点(甚至是调用堆栈),定期打印。

优点:没有看出

缺点:侵入式方法,需将头文件加入到大量源文件的头部,以确保重载的宏能够覆盖所有的new/delete。记录分配点需要加锁(如果你的程序是多线程),而且记录分配要占用大量内存(也是占用的程序内存)。

四、Hook Windows系统API

方法:使用微软的detours库,hook分配内存的系统Api:HeapAlloc/HeapRealloc/HeapFree(new/malloc的底层调用),记录分配点,定期打印。

优点:非侵入式方法,无需修改现有文件(hook api后,分配和释放走到自己的钩子函数中),检查全面,对第三方库、脚本库等等都能统计到。

缺点:记录内存需要占用大量内存,而且多线程环境需要加锁。

五、使用DiagLeak检测

微软出品的内存泄漏分析工具,原理同hookapi方式。配合LDGraph可视化展示内存分配数据,更方便查找泄漏。

1.在IDE工程选项里面配置Release版本也生成调试信息,发布时,将pdb文件和exe文件一起发布。

C++内存泄露检查的5个方法

2.程序运行后,打开LeakDiag,设置Symbol path

C++内存泄露检查的5个方法

3.定期Log下目标进程的内存分配情况,通过LDGraph打印分配增长情况,来发现内存泄漏。

C++内存泄露检查的5个方法

优点:同hookapi方法,非侵入式修改,无需做任何代码改动。跟踪全面。可视化分析堆栈一览无余!

缺点:对性能有影响,hook分配加锁,遍历堆栈。但是不会占用目标进程的自身内存。

六、总结

对于线上生产环境,建议大对象用计数来判断,定位快速准确,几乎无性能开销。在对外测试阶段,使用LeakDiag辅助分析,因为此时并发压力还不 是太大,性能开销还是可以承受。在线上大规模应用阶段,通过HookApi的方法,结合GM指令控制部分时间段的检测,这样可以把对玩家的影响(服务器性 能下降导致延迟)降到最低。

来源:ajie0112的博客

昵    称:
验证码:

相关文档:

  • C++ 简易scoket Server
    C++ 简易scoket Server...
  • C/C++代码静态分析插件:VisualStudio_Scan
    VisualStudio_Scan 是一款开源免费,集成在 Visual Studio 中的 c/c++ 代码静态分析插件,集成了cppcheck,coverity,pclint 等业界优秀的静态分析工具...
  • C++ 时间函数用法
    C++对时间的操作也有许多值得大家注意的地方。最近,在技术群中有很多网友也多次问到过C++语言中对时间的操作、获取和显示等等的问...
  • C语言的SPDY开发包 spdylay
    spdylay 是 C 语言实现对 SPDY v2/3 协议支持的库...
  • C编程语言的编译器:8cc C Compiler
    8CC是一个C编程语言的编译器。它的目的是支持所有C11语言功能,同时尽可能保持代码少而简单。...
  • C/C++代码编辑器 GCCSense
    GCCSense 是一个使用 GCC 代码分析器的智能 C/C++ 开发工具,通过内部编译信息,可提供高级代码自动完成功能,GCCSense 是一个独立的程序,...
  • C++堆内存和栈内存详解
    C++堆内存和栈内存详解...
  • 命令行参数处理的C函数库 longopt
    longopt是一个处理命令行参数的C函数库。...
  • Platinum UPnP SDK - 跨平台的C++库
    Platinum UPnP SDK 是一个跨平台的C++库,利用该库,你可以很容易就构建出DLNA/UPnP控制点(DLNA/UPnP Control Point)和DLNA/UPnP设备(DLNA/UPnP Device)....
  • Simple MySQL-C ORM - 简化C语言访问MySQL
    当你需要在纯C语言的应用程序中访问 MySQL 表中的数据时,是非常繁琐的事情,而该框架可以帮你大量的简化编码的工作,该框架采用 Pyt...
  • 底层的 C 程序库 skalibs
    skalibs 是一组用于一般用途的、底层的 C 程序库,可替换标准 C 库的一些方法,主要用于构建很小的静态二进制文件。...
  • 标准C语言库 Glibc
    Glibc 是提供系统调用和基本函数的 C 库,比如open, malloc, printf等等。所有动态连接的程序都要用到它。...
  • C程序运行的背后
    一个成功的男人背后,至少有一个伟大的女人;一个不成功的男人,至少有一双手。 而一个C程序,无论成功不成功,它的背后一定有...
  • C++二叉查找树实现过程详解
    在数据结构中,有一个奇葩的东西,说它奇葩,那是因为它重要,这就是树。而在树中,二叉树又是当中的贵族。二叉树的一个重要应用...
  • 可移植的C++标准库 Boost
    Boost库是一个经过千锤百炼、可移植、提供源代码的C++库,作为标准库的后备,是C++标准化进程的发动机之一。 Boost库由C++标准委员会库...
  • 高级C的函数库 acl (advanced C library) 介绍
    其实是一个很简单的问题,acl 的英文字母 advanced C library 的缩写(当然,您也可以认为是 a C library 的缩写)。也许有人会问:"现在...
  • WEB开发的C++类库 WebAppLib
    WebAppLib是一系列主要用于类Unix操作系统环境下 WEB开发的C++类库。...
  • C++反射模板库 Template Reflection Library
    trl 是一个用于serialize/deserialize,object hierarchy的C++库,依赖于标准 standard C++预处理宏和模板元编程技术。...
  • 嵌入式系统的C运行库 Newlib
    Newlib是一个面向嵌入式系统的C运行库。最初是由Cygnus Solutions收集组装的一个源代码集合,取名为newlib,现在由Red Hat维护,目前的最新的...
  • GCC的图形化前端 wxgcc
    wxgcc 的全称是:wxpython gcc compiling toolkit ,它是一个在Linux环境下使用的,基于 wxpython 的GCC 编译器图形前端软件,可以用来快速的编译验...