当前位置: 首页 > 科技观察

C++内存泄漏检查的5种方法

时间:2023-03-12 19:04:54 科技观察

1.前言Linux平台上的Valgrind可以非常方便的帮助我们定位内存泄漏,因为Linux在开发领域的使用场景大多是运行服务器,加上其开源的属性,相对来说说起来,很容易形成处理问题的“统一”标准。在Windows平台上,服务端和客户端开发者使用的调试方法是有很大区别的。结合本人的实际经验,整理出以下几种常见的定位内存泄漏的方法。注意:我们分析的前提是Release版本,因为在Debug环境下,通过VLD库或者CRT库本身的内存泄漏检测功能来分析内存泄漏比较简单。但是服务器有很多问题是在线并发压力下才出现的,所以讨论Debug版本的调试方式意义不大。2、对象计数法:对象构造时计数++,销毁时-每隔一段时间打印对象个数优点:无性能开销,几乎不额外占用内存。定位结果准确。缺点:侵入式方法,需要修改已有代码,无法修改代码,无法定位第三方库、STL容器、脚本泄露等。3、重载new和delete方法:重载new/delete,记录分配点(甚至是调用栈),定时打印。优点:没见过缺点:侵入式方法,需要在大量源文件的头部加上头文件,保证重载的宏能覆盖所有的new/delete。记录分配点需要加锁(如果你的程序是多线程的),记录分配占用内存很大(也是占用程序内存)。4、HookWindows系统API方法:使用微软的detours库,hook分配内存的系统Api:HeapAlloc/HeapRealloc/HeapFree(new/malloc的底层调用),记录分配点,定时打印。优点:非侵入式方式,无需修改现有文件(hookapi后,allocation和release去自己的hook函数),检查全面,可以获取第三方库、脚本库等的统计信息。缺点:录制内存需要大量内存,多线程环境需要加锁。5、使用DiagLeak检测微软出品的内存泄漏分析工具,原理同hookapi方法。配合LDGraph可视化展示内存分配数据,更容易发现内存泄漏。1.在IDE项目选项中配置Release版本,也能生成调试信息。发布的时候把pdb文件和exe文件一起发布。2、程序运行后,打开LeakDiag,设置Symbol路径3、定时记录目标进程的内存分配情况,通过LDGraph打印分配增长情况,发现内存泄漏。优点:同hookapi方法一样,非侵入式修改,不需要做任何代码改动。跟踪是全面的。可视化分析堆栈一目了然!缺点:对性能有影响,hook分配锁,遍历栈。但不会占用目标进程自身的内存。6.总结对于线上生产环境,建议大对象通过计数来判断。定位快速准确,几乎没有性能开销。外测阶段使用LeakDiag辅助分析,因为此时并发压力还不算太高,性能开销还是可以承受的。在线上大规模应用阶段,通过HookApi的方式,结合GM指令控制一些时间段的检测,可以将对玩家的影响(服务器性能下降造成的延迟)降到最低。