C++ C++;COM服务器内存使用随时间增加-WinDBG分析

C++ C++;COM服务器内存使用随时间增加-WinDBG分析,c++,memory-leaks,com,windbg,C++,Memory Leaks,Com,Windbg,我有一个ATL COM服务器的问题,随着时间的推移,它正在使用大量内存。我怀疑内存泄漏,但无法查明原因。该服务在48小时的压力测试过程中缓慢增加内存 下面是我在WinDBG中收集的,通过分析1小时后的过程。我在这里放置了一些占据大部分内存的对象 size #blocks total ( %) (percent of total busy bytes) 190 6c3 - a90b0 (32.86) 30 1507 - 3f

我有一个ATL COM服务器的问题,随着时间的推移,它正在使用大量内存。我怀疑内存泄漏,但无法查明原因。该服务在48小时的压力测试过程中缓慢增加内存

下面是我在WinDBG中收集的,通过分析1小时后的过程。我在这里放置了一些占据大部分内存的对象

size     #blocks     total     ( %) (percent of total busy bytes)
190        6c3      - a90b0  (32.86)
30         1507     - 3f150  (12.26)

!heap -flt s 190

!heap -p -a 0000000002ae0ee0
address 0000000002ae0ee0 found in
_HEAP @ 1a40000
          HEAP_ENTRY Size Prev Flags            UserPtr UserSize - state
    0000000002ae0eb0 001c 0000  [00]   0000000002ae0ee0    00190 - (busy)
      combase!CStdIdentity::`vftable'
    7ffd1aa71be7 ntdll!RtlAllocateHeap+0x000000000006fb17
    7ffd18676158 combase!CIDObject::GetOrCreateStdID+0x0000000000000128
    7ffd1867a788 combase!CDestObjectWrapper::MarshalInterface+0x00000000000006ca
    7ffd186795c2 combase!CoMarshalInterface+0x00000000000001a2
    7ffd1868145f combase!MarshalHelperMulti+0x000000000000006f
    7ffd1868139f combase!GetInstanceHelperMulti+0x0000000000000083
    7ffd18681129 combase!CObjServer::CreateInstance+0x0000000000000467
    7ffd18b02385 RPCRT4!Invoke+0x0000000000000065
    7ffd18b0ae16 RPCRT4!NdrStubCall2+0x000000000000038b
    7ffd18b170eb RPCRT4!NdrStubCall3+0x000000000000014a
    7ffd187a05ff combase!CStdStubBuffer_Invoke+0x0000000000000067
    7ffd187a04d9 combase!SyncStubInvoke+0x0000000000000306
    7ffd18633fc9 combase!CCtxComChnl::ContextInvoke+0x0000000000000279
    7ffd187a13ff combase!AppInvoke+0x000000000000018f
    7ffd187a0e9b combase!ComInvokeWithLockAndIPID+0x0000000000000661
    7ffd187a184e combase!ThreadInvoke+0x0000000000000481
    7ffd18b02614 RPCRT4!DispatchToStubInCNoAvrf+0x0000000000000014
    7ffd18b02517 RPCRT4!RPC_INTERFACE::DispatchToStubWorker+0x0000000000000177
    7ffd18b16ebf RPCRT4!LRPC_SCALL::DispatchRequest+0x0000000000000531
    7ffd18b02cc1 RPCRT4!LRPC_SCALL::HandleRequest+0x0000000000000201
    7ffd18b02a97 RPCRT4!LRPC_SASSOCIATION::HandleRequest+0x0000000000000237
    7ffd18b01d04 RPCRT4!LRPC_ADDRESS::ProcessIO+0x000000000000036d
    7ffd18b01afe RPCRT4!LrpcIoComplete+0x00000000000000ae
    7ffd1a9fd394 ntdll!TppAlpcpExecuteCallback+0x0000000000000204
    7ffd1a9fb96d ntdll!TppWorkerThread+0x00000000000003ad
    7ffd184f15bd KERNEL32!BaseThreadInitThunk+0x000000000000000d
    7ffd1aa343d1 ntdll!RtlUserThreadStart+0x000000000000001d

!heap -flt s 30
!heap -p -a 0000000002af5960
address 0000000002af5960 found in
_HEAP @ 1a40000
          HEAP_ENTRY Size Prev Flags            UserPtr UserSize - state
    0000000002af5930 0006 0000  [00]   0000000002af5960    00030 - (busy)
    7ffd1aa71be7 ntdll!RtlAllocateHeap+0x000000000006fb17
    7ffd1a9e0056 ntdll!RtlpAddDebugInfoToCriticalSection+0x0000000000000012
    7ffd1aa79db4 ntdll!RtlInitializeCriticalSectionAndSpinCount+0x0000000000055dd4
    7ffd18674b24 combase!CStdIdentity::CStdIdentity+0x00000000000002d4
    7ffd1867618d combase!CIDObject::GetOrCreateStdID+0x000000000000015d
    7ffd1867a788 combase!CDestObjectWrapper::MarshalInterface+0x00000000000006ca
    7ffd186795c2 combase!CoMarshalInterface+0x00000000000001a2
    7ffd1868145f combase!MarshalHelperMulti+0x000000000000006f
    7ffd1868139f combase!GetInstanceHelperMulti+0x0000000000000083
    7ffd18681129 combase!CObjServer::CreateInstance+0x0000000000000467
    7ffd18b02385 RPCRT4!Invoke+0x0000000000000065
    7ffd18b0ae16 RPCRT4!NdrStubCall2+0x000000000000038b
    7ffd18b170eb RPCRT4!NdrStubCall3+0x000000000000014a
    7ffd187a05ff combase!CStdStubBuffer_Invoke+0x0000000000000067
    7ffd187a04d9 combase!SyncStubInvoke+0x0000000000000306
    7ffd18633fc9 combase!CCtxComChnl::ContextInvoke+0x0000000000000279
    7ffd187a13ff combase!AppInvoke+0x000000000000018f
    7ffd187a0e9b combase!ComInvokeWithLockAndIPID+0x0000000000000661
    7ffd187a184e combase!ThreadInvoke+0x0000000000000481
    7ffd18b02614 RPCRT4!DispatchToStubInCNoAvrf+0x0000000000000014
    7ffd18b02517 RPCRT4!RPC_INTERFACE::DispatchToStubWorker+0x0000000000000177
    7ffd18b16ebf RPCRT4!LRPC_SCALL::DispatchRequest+0x0000000000000531
    7ffd18b02cc1 RPCRT4!LRPC_SCALL::HandleRequest+0x0000000000000201
    7ffd18b02a97 RPCRT4!LRPC_SASSOCIATION::HandleRequest+0x0000000000000237
    7ffd18b01d04 RPCRT4!LRPC_ADDRESS::ProcessIO+0x000000000000036d
    7ffd18b01afe RPCRT4!LrpcIoComplete+0x00000000000000ae
    7ffd1a9fd394 ntdll!TppAlpcpExecuteCallback+0x0000000000000204
    7ffd1a9fb96d ntdll!TppWorkerThread+0x00000000000003ad
    7ffd184f15bd KERNEL32!BaseThreadInitThunk+0x000000000000000d
    7ffd1aa343d1 ntdll!RtlUserThreadStart+0x000000000000001d
其他对象:

size     #blocks     total     ( %) (percent of total busy bytes)
48        6c2       - 1e690  (91.91)
1000        1       - 1000   (3.02)

!heap -flt s 48
!heap -p -a 0000000002ab8000
address 0000000002ab8000 found in
_HEAP @ 1a40000
          HEAP_ENTRY Size Prev Flags            UserPtr UserSize - state
    0000000002ab7fd0 0007 0000  [00]   0000000002ab8000    00048 - (busy)
      combase!g_ForwardingVtbl
    7ffd1aa71be7 ntdll!RtlAllocateHeap+0x000000000006fb17
    7ffd18674115 combase!CreateStubFromTypeInfo+0x0000000000000061
    7ffd18b58f63 RPCRT4!CreateStubFromTypeInfo+0x0000000000000043
    7ffd1908dcf8 OLEAUT32!CUnivStubWrapper::Invoke+0x0000000000000098
    7ffd187a04d9 combase!SyncStubInvoke+0x0000000000000306
    7ffd18633fc9 combase!CCtxComChnl::ContextInvoke+0x0000000000000279
    7ffd187a13ff combase!AppInvoke+0x000000000000018f
    7ffd187a0e9b combase!ComInvokeWithLockAndIPID+0x0000000000000661
    7ffd187a184e combase!ThreadInvoke+0x0000000000000481
    7ffd18b02614 RPCRT4!DispatchToStubInCNoAvrf+0x0000000000000014
    7ffd18b02517 RPCRT4!RPC_INTERFACE::DispatchToStubWorker+0x0000000000000177
    7ffd18b16ebf RPCRT4!LRPC_SCALL::DispatchRequest+0x0000000000000531
    7ffd18b02cc1 RPCRT4!LRPC_SCALL::HandleRequest+0x0000000000000201
    7ffd18b02a97 RPCRT4!LRPC_SASSOCIATION::HandleRequest+0x0000000000000237
    7ffd18b01d04 RPCRT4!LRPC_ADDRESS::ProcessIO+0x000000000000036d
    7ffd18b01afe RPCRT4!LrpcIoComplete+0x00000000000000ae
    7ffd1a9fd394 ntdll!TppAlpcpExecuteCallback+0x0000000000000204
    7ffd1a9fb96d ntdll!TppWorkerThread+0x00000000000003ad
    7ffd184f15bd KERNEL32!BaseThreadInitThunk+0x000000000000000d
    7ffd1aa343d1 ntdll!RtlUserThreadStart+0x000000000000001d

!heap -p -a 000000000282f280
address 000000000282f280 found in
_HEAP @ 20a0000
          HEAP_ENTRY Size Prev Flags            UserPtr UserSize - state
    000000000282f250 0007 0000  [00]   000000000282f280    00048 - (busy)
      ccprovsp!ATL::CComObject<MyCOM>::`vftable'
    7ffd1aa71be7 ntdll!RtlAllocateHeap+0x000000000006fb17
    140028c87 ccprovsp!malloc+0x0000000000000067
    14002815e ccprovsp!operator new+0x000000000000000e
    14000280b ccprovsp!ATL::CComCreator<ATL::CComObject<MyCOM> >::CreateInstance+0x000000000000005b
    14000239c ccprovsp!ATL::CComCreator2<ATL::CComCreator<ATL::CComObject<MyCOM> >,ATL::CComFailCreator<-2147221232> >::CreateInstance+0x000000000000002c
    1400085a7 ccprovsp!ATL::CComClassFactory::CreateInstance+0x0000000000000077
    7ffd1868134c combase!GetInstanceHelperMulti+0x0000000000000034
    7ffd18681129 combase!CObjServer::CreateInstance+0x0000000000000467
    7ffd18b02385 RPCRT4!Invoke+0x0000000000000065
    7ffd18b0ae16 RPCRT4!NdrStubCall2+0x000000000000038b
    7ffd18b170eb RPCRT4!NdrStubCall3+0x000000000000014a
    7ffd187a05ff combase!CStdStubBuffer_Invoke+0x0000000000000067
    7ffd187a04d9 combase!SyncStubInvoke+0x0000000000000306
    7ffd18633fc9 combase!CCtxComChnl::ContextInvoke+0x0000000000000279
    7ffd187a13ff combase!AppInvoke+0x000000000000018f
    7ffd187a0e9b combase!ComInvokeWithLockAndIPID+0x0000000000000661
    7ffd187a184e combase!ThreadInvoke+0x0000000000000481
    7ffd18b02614 RPCRT4!DispatchToStubInCNoAvrf+0x0000000000000014
    7ffd18b02517 RPCRT4!RPC_INTERFACE::DispatchToStubWorker+0x0000000000000177
    7ffd18b16ebf RPCRT4!LRPC_SCALL::DispatchRequest+0x0000000000000531
    7ffd18b02cc1 RPCRT4!LRPC_SCALL::HandleRequest+0x0000000000000201
    7ffd18b02a97 RPCRT4!LRPC_SASSOCIATION::HandleRequest+0x0000000000000237
    7ffd18b01d04 RPCRT4!LRPC_ADDRESS::ProcessIO+0x000000000000036d
    7ffd18b01afe RPCRT4!LrpcIoComplete+0x00000000000000ae
    7ffd1a9fd394 ntdll!TppAlpcpExecuteCallback+0x0000000000000204
    7ffd1a9fb96d ntdll!TppWorkerThread+0x00000000000003ad
    7ffd184f15bd KERNEL32!BaseThreadInitThunk+0x000000000000000d
    7ffd1aa343d1 ntdll!RtlUserThreadStart+0x000000000000001d
size#块总数(%)(占总忙字节的百分比)
48 6c2-1e690(91.91)
1000        1       - 1000   (3.02)
!堆-flt s 48
!堆-p-a 000000000 2AB8000
在中找到地址000000000 2AB8000
_堆@1a40000
HEAP_条目大小Prev标志UserPtr UserSize-状态
000000000 2AB7FD0 0007 0000[00]000000000 2AB8000 00048-(忙)
康伯斯!g_转发vtbl
7ffd1aa71be7 ntdll!RTLALLOCATECHEAP+0x000000000006fb17
7ffd18674115 combase!CreateStubFromTypeInfo+0x0000000000000061
7ffd18b58f63 RPCRT4!CreateStubFromTypeInfo+0x0000000000000043
7ffd1908dcf8 OLEAUT32!CUnivStubWrapper::Invoke+0x0000000000000098
7ffd187a04d9战斗基地!SyncStubInvoke+0x0000000000000306
7ffd18633fc9战斗基地!CCtxComChnl::ContextInvoke+0x0000000000000279
7ffd187a13ff战斗基地!AppInvoke+0x000000000000018f
7ffd187a0e9b战斗基地!ComInVokeWithLockandPID+0x0000000000000661
7ffd187a184e combase!ThreadInvoke+0x0000000000000481
7ffd18b02614 RPCRT4!DispatchToStubInCNoAvrf+0x0000000000000014
7ffd18b02517 RPCRT4!RPC_接口::DispatchToStubWorker+0x0000000000000177
7ffd18b16ebf RPCRT4!LRPC_SCALL::DispatchRequest+0x0000000000000531
7ffd18b02cc1 RPCRT4!LRPC_SCALL::HandlerRequest+0x0000000000000201
7ffd18b02a97 RPCRT4!LRPC_SaSociation::HandlerRequest+0x0000000000000237
7ffd18b01d04 RPCRT4!LRPC_地址::进程+0x000000000000036d
7ffd18b01afe RPCRT4!LrpcIoComplete+0x00000000000000ae
7ffd1a9fd394 ntdll!TPAPLPCPExecuteCallback+0x0000000000000204
7ffd1a9fb96d ntdll!TppWorkerThread+0x00000000000003ad
7ffd184f15bd内核32!BaseThreadInitThunk+0x000000000000000d
7ffd1aa343d1 ntdll!RtlUserThreadStart+0x000000000000001d
!堆-p-a 000000000 282F280
在中找到地址000000000 282F280
_堆@20a0000
HEAP_条目大小Prev标志UserPtr UserSize-状态
000000000 282F250 0007 0000[00]000000000 282F280 00048-(忙)
ccprovsp!ATL::ccombject::`vftable'
7ffd1aa71be7 ntdll!RTLALLOCATECHEAP+0x000000000006fb17
140028c87 ccprovsp!malloc+0x0000000000000067
14002815e ccprovsp!新运算符+0x000000000000000e
14000280b ccprovsp!ATL::CComCreator::CreateInstance+0x000000000000005b
14000239c ccprovsp!ATL::CComCreator2::CreateInstance+0x000000000000002c
1400085a7 ccprovsp!ATL::CComClassFactory::CreateInstance+0x0000000000000077
7ffd1868134c combase!GetInstanceHelperMulti+0x0000000000000034
7ffd18681129战斗基地!CObjServer::CreateInstance+0x0000000000000467
7ffd18b02385 RPCRT4!调用+0x0000000000000065
7ffd18b0ae16 RPCRT4!NdrStubCall2+0x000000000000038b
7ffd18b170eb RPCRT4!NdrStubCall3+0x000000000000014a
7ffd187a05ff combase!CSTDSubbuffer_调用+0x0000000000000067
7ffd187a04d9战斗基地!SyncStubInvoke+0x0000000000000306
7ffd18633fc9战斗基地!CCtxComChnl::ContextInvoke+0x0000000000000279
7ffd187a13ff战斗基地!AppInvoke+0x000000000000018f
7ffd187a0e9b战斗基地!ComInVokeWithLockandPID+0x0000000000000661
7ffd187a184e combase!ThreadInvoke+0x0000000000000481
7ffd18b02614 RPCRT4!DispatchToStubInCNoAvrf+0x0000000000000014
7ffd18b02517 RPCRT4!RPC_接口::DispatchToStubWorker+0x0000000000000177
7ffd18b16ebf RPCRT4!LRPC_SCALL::DispatchRequest+0x0000000000000531
7ffd18b02cc1 RPCRT4!LRPC_SCALL::HandlerRequest+0x0000000000000201
7ffd18b02a97 RPCRT4!LRPC_SaSociation::HandlerRequest+0x0000000000000237
7ffd18b01d04 RPCRT4!LRPC_地址::进程+0x000000000000036d
7ffd18b01afe RPCRT4!LrpcIoComplete+0x00000000000000ae
7ffd1a9fd394 ntdll!TPAPLPCPExecuteCallback+0x0000000000000204
7ffd1a9fb96d ntdll!TppWorkerThread+0x00000000000003ad
7ffd184f15bd内核32!BaseThreadInitThunk+0x000000000000000d
7ffd1aa343d1 ntdll!RtlUserThreadStart+0x000000000000001d

有没有关于我下一步应该做什么的提示?

首先,似乎您已经正确设置了GFlags来跟踪内存分配。这是一件好事,肯定会有助于找到问题所在。但是,您发布的对象毫无意义,因为我们无法判断它们当前是否应该使用

在WinDbg中进行分析相当困难,需要大量的手动工作。幸运的是,在这种情况下,有一种方法会有所帮助

如何继续

因为您可以在相对较短的时间内重现问题(1小时内600 kB就可以了),所以请这样做。创建一个场景,在这个场景中,您在应用程序中反复达到相同的状态,并且(在您看来)所有内存都应该再次被释放。在一小时以上,始终在达到该状态时创建UMDH快照。稍后,分析日志文件(这种方法称为“模式2”)

UMDH将按调用堆栈对所有内存分配进行排序。若你们设法画出一个分配随时间变化的图表,比如在Excel中,你们可能会看到一条上升的线。这可能就是罪魁祸首。您可以尝试生成这样的图(我以前从未使用过,因为我有自己的工具来创建图,不幸的是,现在还没有准备好发布)

当您知道丢失的对象的类型时,您就知道它被分配到哪里(从调用堆栈)。然后执行代码检查并找到应该发布代码的地方。试着找出为什么它没有发布(这是真正困难的部分)

进一步阅读

塔里克·苏拉米的书在第8章介绍了UMDH

你可能还想读或听一些在线的t