托管 C++内存泄漏

发布于 2024-09-14 03:55:50 字数 2793 浏览 2 评论 0原文

每当 DCOM 服务器(c++ DCOM 服务器)中的新 RPC 线程调用以下托管 C++ 方法时,我都会发生内存泄漏

void CToolDataClient::SetLotManagerActive(bool bLotManagerActive)
{
  if( m_toolDataManager != nullptr)
  {
   m_toolDataManager->LotActive = bLotManagerActive;
  }
}

我使用以下代码获取托管 C++ 对象指针

typedef bool (*FPTR_CREATEINTERFACE)(CToolDataInterface ** ppInterface);

FPTR_CREATEINTERFACE fnptr = (FPTR_CREATEINTERFACE)GetProcAddress(hModule,(LPTSTR)"CreateInstance");
if ( NULL != fnptr ) 
{
  CICELogger::Instance()->LogMessage("CToolDataManager::CToolDataManager", Information, 
            "Created instance of DataManagerBridge");
  fnptr(&m_pToolDataInterface);
}

这就是我在 DCOME 服务器 C++ 中调用托管调用的方式 下面给出的调用堆栈部分

void CToolDataManager::SetLotManagerActive(bool bLotManagerActive)
{
    if(m_pToolDataInterface != NULL)
    {
        m_pToolDataInterface->SetLotManagerActive(bLotManagerActive);
    }
}

指示了内存泄漏的位置。有什么办法可以解决这个内存泄漏吗?请帮我

 ntdll!RtlDebugAllocateHeap+000000E1
 ntdll!RtlAllocateHeapSlowly+00000044
 ntdll!RtlAllocateHeap+00000E64
 mscorwks!EEHeapAlloc+00000142
 mscorwks!EEHeapAllocInProcessHeap+00000052
 **mscorwks!operator new[]+00000025
 mscorwks!SetupThread+00000238
 mscorwks!IJWNOADThunk::FindThunkTarget+00000019
 mscorwks!IJWNOADThunkJumpTargetHelper+0000000B
 mscorwks!IJWNOADThunkJumpTarget+00000048
 ICEScheduler!CToolDataManager::SetLotManagerActive+00000025** (e:\projects\ice\ice_dev\trunk\source\application source\iceschedulersystem\icescheduler\tooldatamanager.cpp, 250)
 ICEScheduler!SetLotManagerActive+00000014 (e:\projects\ice\ice_dev\trunk\source\application source\iceschedulersystem\icescheduler\schddllapi.cpp, 589)
 ICELotControl!CLotDetailsHandler::SetLotManagerStatus+0000006C (e:\projects\ice\ice_dev\source\application source\icelotsystem\icelotcontrol\lotdetailshandler.cpp, 1823)
 ICELotControl!CLotManager::StartJob+00000266 (e:\projects\ice\ice_dev\source\application source\icelotsystem\icelotcontrol\lotmanager.cpp, 205)
 RPCRT4!Invoke+00000030
 RPCRT4!NdrStubCall2+00000297
 RPCRT4!CStdStubBuffer_Invoke+0000003F
 OLEAUT32!CUnivStubWrapper::Invoke+000000C5
 ole32!SyncStubInvoke+00000033
 ole32!StubInvoke+000000A7
 ole32!CCtxComChnl::ContextInvoke+000000E3
 ole32!MTAInvoke+0000001A
 ole32!AppInvoke+0000009C
 ole32!ComInvokeWithLockAndIPID+000002E0
 ole32!ThreadInvoke+000001CD
 RPCRT4!DispatchToStubInC+00000038
 RPCRT4!RPC_INTERFACE::DispatchToStubWorker+00000113
 RPCRT4!RPC_INTERFACE::DispatchToStub+00000084
 RPCRT4!RPC_INTERFACE::DispatchToStubWithObject+000000C0
 RPCRT4!LRPC_SCALL::DealWithRequestMessage+000002CD
 RPCRT4!LRPC_ADDRESS::DealWithLRPCRequest+0000016D
 RPCRT4!LRPC_ADDRESS::ReceiveLotsaCalls+0000028F

I am getting a memory leak whenver a new RPC thread in a DCOM server (c++ DCOM server) invokes the following managed C++ method

void CToolDataClient::SetLotManagerActive(bool bLotManagerActive)
{
  if( m_toolDataManager != nullptr)
  {
   m_toolDataManager->LotActive = bLotManagerActive;
  }
}

I get the managed C++ object pointer using the floowing code

typedef bool (*FPTR_CREATEINTERFACE)(CToolDataInterface ** ppInterface);

FPTR_CREATEINTERFACE fnptr = (FPTR_CREATEINTERFACE)GetProcAddress(hModule,(LPTSTR)"CreateInstance");
if ( NULL != fnptr ) 
{
  CICELogger::Instance()->LogMessage("CToolDataManager::CToolDataManager", Information, 
            "Created instance of DataManagerBridge");
  fnptr(&m_pToolDataInterface);
}

This is how I invoke the managed call in the DCOME server C++ portion

void CToolDataManager::SetLotManagerActive(bool bLotManagerActive)
{
    if(m_pToolDataInterface != NULL)
    {
        m_pToolDataInterface->SetLotManagerActive(bLotManagerActive);
    }
}

The callstack given below indicate the location of the memory leak . Is there any ways to solve this memory leak? Please help me

 ntdll!RtlDebugAllocateHeap+000000E1
 ntdll!RtlAllocateHeapSlowly+00000044
 ntdll!RtlAllocateHeap+00000E64
 mscorwks!EEHeapAlloc+00000142
 mscorwks!EEHeapAllocInProcessHeap+00000052
 **mscorwks!operator new[]+00000025
 mscorwks!SetupThread+00000238
 mscorwks!IJWNOADThunk::FindThunkTarget+00000019
 mscorwks!IJWNOADThunkJumpTargetHelper+0000000B
 mscorwks!IJWNOADThunkJumpTarget+00000048
 ICEScheduler!CToolDataManager::SetLotManagerActive+00000025** (e:\projects\ice\ice_dev\trunk\source\application source\iceschedulersystem\icescheduler\tooldatamanager.cpp, 250)
 ICEScheduler!SetLotManagerActive+00000014 (e:\projects\ice\ice_dev\trunk\source\application source\iceschedulersystem\icescheduler\schddllapi.cpp, 589)
 ICELotControl!CLotDetailsHandler::SetLotManagerStatus+0000006C (e:\projects\ice\ice_dev\source\application source\icelotsystem\icelotcontrol\lotdetailshandler.cpp, 1823)
 ICELotControl!CLotManager::StartJob+00000266 (e:\projects\ice\ice_dev\source\application source\icelotsystem\icelotcontrol\lotmanager.cpp, 205)
 RPCRT4!Invoke+00000030
 RPCRT4!NdrStubCall2+00000297
 RPCRT4!CStdStubBuffer_Invoke+0000003F
 OLEAUT32!CUnivStubWrapper::Invoke+000000C5
 ole32!SyncStubInvoke+00000033
 ole32!StubInvoke+000000A7
 ole32!CCtxComChnl::ContextInvoke+000000E3
 ole32!MTAInvoke+0000001A
 ole32!AppInvoke+0000009C
 ole32!ComInvokeWithLockAndIPID+000002E0
 ole32!ThreadInvoke+000001CD
 RPCRT4!DispatchToStubInC+00000038
 RPCRT4!RPC_INTERFACE::DispatchToStubWorker+00000113
 RPCRT4!RPC_INTERFACE::DispatchToStub+00000084
 RPCRT4!RPC_INTERFACE::DispatchToStubWithObject+000000C0
 RPCRT4!LRPC_SCALL::DealWithRequestMessage+000002CD
 RPCRT4!LRPC_ADDRESS::DealWithLRPCRequest+0000016D
 RPCRT4!LRPC_ADDRESS::ReceiveLotsaCalls+0000028F

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

阳光的暖冬 2024-09-21 03:55:51

首先,LotActive是成员变量/字段(纯数据)还是属性?

我认为它是一个属性,在设置它之前,JIT 必须编译 setter 的代码。在桌面 .NET 中,JIT 编译过程生成的本机代码不会被垃圾收集,而是在 AppDomain 的生命周期内存在,因此它可能看起来像泄漏。

您能否检查对此函数的每次调用是否泄漏另一个对象,或者泄漏仅发生一次?

First, is LotActive a member variable/field (pure data) or a property?

I think that it is a property, and before it can be set, the JIT has to compile the code for the setter. In desktop .NET, native code produced by the JIT compilation process is not garbage collected, instead it exists for the lifetime of the AppDomain, so it could look like a leak.

Can you check whether each call to this function leaks another object, or the leak just occurs once?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文