C++程序如何精确查找内存泄漏

分享到:
本文主要介绍了C++程序在Windows平台上各种定位内存泄漏的方法,并对比了它们的优缺点。

一、前言

        在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可视化展示内存分配数据,更方便查找泄漏。

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

C++程序如何精确查找内存泄漏

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

C++程序如何精确查找内存泄漏

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

C++程序如何精确查找内存泄漏

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

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

六、总结

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

以上方法,我将后续的博客中逐一详细介绍,文中提到到detours库和LeakDiag工具,想了解的朋友,可以上codeprojet上搜索下相关介绍,如果要上google查找资料,也可以上这里。如果大家有新方法也可留言讨论,我们共同完善这一系列的介绍文章。

昵    称:
验证码:

相关文档:

  • 如何编写一个PHP的C扩展
    C是静态编译的,执行效率比PHP代码高很多。同样的运算代码,使用C来开发,性能会比PHP要提升数百倍。IO操作如CURL,因为耗时主要在IOWa...
  • Neptune C++ Runtime Library
    一个可以在多个平台C++开发环境下编译运行的C++运行库。其中包括了对多个C++库和平台SDK(HTTP/TCP/UDP/XML, Thread/Message, String, List/Stack/Queue/M...
  • 使用libcurl 函数库获取网页数据代码
    使用libcurl 函数库获取网页数据代码...
  • 纯C语言INI文件解析
    在一个跨平台( Android 、Windows、Linux )项目中配置文件用 INI 格式,自己写了个解析库,纯C语言的,简单好用。 可以解析 INI 格式...
  • C++中对字符串进行插入、替换、删除操作
    C++中对字符串进行插入、替换、删除操作...
  • C++用户界面设计器 Glade
    Glade是RAD (快速应用开发)工具,用于创建基于GTK 工具包和GNOME桌面。...
  • Socket 编程 详解
    对TCP/IP、UDP、Socket编程这些词你不会很陌生吧?随着网络技术的发展,这些词充斥着我们的耳朵。TCP/IP(Transmission Control Protocol/Internet Pro...
  • C++模板库 Standard Portable Library
    Standard Portable Library 是一个指针友好的 C/C++ 标准模板库的替代产品,它所提供的 API 跟 Java 或者是 .NET 的语言类似,包括公用的数据结构...
  • C++线程池的设计与测试
    编写了一个最基本的线程池类,处理用c_work表示的工作任务。...
  • C语言内存泄漏检测工具 MemLeak
    MemLeak 是一个C语言内存泄漏检测工具。...
  • C语言协程库 cgreenlet
    和子例程一样,协程也是一种程序组件。相对子例程而言,协程更加一般和灵活,但在实践中使用没有子例程广泛。协程源自 Simula 和 Mod...
  • C++书籍推荐
    本文内容来自国外著名编程问答网站Stackoverflow评选的C++推荐书单!推荐大家看原版英文,但这些书大部分也都有中文版!...
  • 标准C++类库 STDCXX
    Apache的C++ 标准库项目(代号stdcxx ,发音为“standard C++ library” ,而不是STDCXX )是一个集算法,容器,迭代器等等功能的C++类库。...
  • 内存分配模块 nedmalloc
    nedmalloc 是一个可选的malloc内存分配的实现,主要是适应多线程无锁操作,基于 dlmalloc 2.8.3 。...
  • C++代码检查工具:Vera++
    Vera++ 是一个可编程的工具用来对 C++ 源码进行校验、分析和转换。主要是一个 C++ 源码解析引擎。 主要做代码风格的检查...
  • GCCAVR编译器 WinAVR
    WinAVR-20070525 是Windows 版的 GCCAVR编译器,GCCAVR是一款免费的编译器,编译功能也挺强的,有一点不好就是不是那容易入手。总得来说还是...
  • C++之父谈关于C++的五个需要被重新认识的观点(上)
    概述:学习和使用过C++的人几乎都曾经听说过下面的五个关于C++的观点,并且对这些话笃信不已,那么真实的情况是怎么样的呢?本文的...
  • linux c 内存泄露检测工具:valgrind
    Linux c/c++上常用内存泄露检测工具有valgrind, Rational purify。Valgrind免费。Valgrind 可以在 32 位或 64 位 PowerPC/Linux 内核上工作。...
  • C++系统调用库 CSCall++
    CSCall++ 是对常用的一些系统调用进行封装的 C++ 库,主要包括:线程、文件、FIFOs、串行IO、socket通讯和目录处理等。...
  • 轻量级的 C++ 库 UCommon
    UCommon 是一个轻量级的 C++ 库,使用 C++ 设计模式,适合用于嵌入式应用的开发,例如使用 uClibc 和 POSIX 线程支持。...