调查内存泄漏(Investigating Memory Leak)

2019-09-16 08:33发布

我们在我们的应用程序缓慢内存泄漏问题,我已经在试图analyize对泄漏的原因通过以下步骤已经过去了:

  1. 在GFlags在启用用户模式堆栈跟踪数据库
  2. 在WinDbg中,键入以下命令:堆-stat -h 125万 (其中125万是有泄漏堆的地址)比较多个转储后,我看到大小0xC的的内存块,随着时间的推移增加,可能是被泄漏的内存。
  3. 键入以下命令:堆-flt SC给那些分配和最终的UserPtr:
  4. 打字堆-p一些这些地址的-a地址总是显示下面的分配调用堆栈:

0:000>堆-p -a 10576ef8

address 10576ef8 found in
_HEAP @ 1250000
  HEAP_ENTRY Size Prev Flags    UserPtr UserSize - state
    10576ed0 000a 0000  [03]   10576ef8    0000c - (busy)
    mscoreei!CLRRuntimeInfoImpl::`vftable'
    7c94b244 ntdll!RtlAllocateHeapSlowly+0x00000044
    7c919c0c ntdll!RtlAllocateHeap+0x00000e64
    603b14a4 mscoreei!UtilExecutionEngine::ClrHeapAlloc+0x00000014
    603b14cb mscoreei!ClrHeapAlloc+0x00000023
    603b14f7 mscoreei!ClrAllocInProcessHeapBootstrap+0x0000002e
    603b1614 mscoreei!operator new[]+0x0000002b
    603d402b +0x0000005f
    603d5142 mscoreei!GetThunkUseState+0x00000025
    603d6fe8 mscoreei!_CorDllMain+0x00000056
    79015012 mscoree!ShellShim__CorDllMain+0x000000ad
    7c90118a ntdll!LdrpCallInitRoutine+0x00000014
    7c919a6d ntdll!LdrpInitializeThread+0x000000c0
    7c9198e6 ntdll!_LdrpInitialize+0x00000219
    7c90e457 ntdll!KiUserApcDispatcher+0x00000007

这看起来像线程初始化调用堆栈,但我需要知道的比这更多。 什么是下一个步骤,你会建议,以把手指在对泄漏的确切原因做。

Answer 1:

使用GFlags时记录的堆栈不使用.PDB,往往不正确完成。 既然你已经查明泄漏下来在给定的堆特定的大小,你可以尝试设置在RtlAllocateHeap现场休息,检查堆栈,用适当的符号WinDbg的。 我已经使用了一些成功以下。 你必须编辑以适合您的堆和大小。

 $$ Display stack if heap handle eq 0x00310000 and size is  0x1303
 $$ ====================================================================
bp ntdll!RtlAllocateHeap "j ((poi(@esp+4) = 0x00310000) & (poi(@esp+c) = 0x1303) )'k';'gc'" 

也许你再得到罪犯另一个堆栈和其他的想法。



Answer 2:

的第一件事是,新的运营商是new []运营商那么有没有一个相应的delete[]调用,而不是一个普通的旧delete通话?

如果你怀疑这个代码,我会把测试工具围绕它,比如把它放在一个循环,并执行它100或1000倍,它仍泄漏和比例。

您还可以使用进程管理器或编程方式使用测量内存增加GetProcessInformation 。

另一个明显的事情是看当你注释掉调用这个函数会发生什么,莫非是内存泄漏消失? 你可能需要做一个二进制的印章,如果可能的代码被注释掉的代码,但是,改变代码的行为可能会导致更多的问题或者相关的代码路径问题,这样可以减少一半(大约)每一次可能的可疑代码导致内存泄漏或奇怪的行为。

编辑忽略以下看到,因为你是在托管环境中工作。

您也可以考虑使用STL或更好的提升引用计数指针类似的shared_ptr或scoped_array的阵列结构来管理对象的生命周期。



文章来源: Investigating Memory Leak