【发布时间】:2018-04-27 14:18:36
【问题描述】:
我正在调试一些遗留代码。它加载一个用户定义的 COM 对象,允许用户调用其中的函数,然后释放它。但是,我们发现每次加载和卸载 COM 对象时,都会发生内存泄漏。作为测试,我们更改了代码以加载并挂起它,并继续重复使用它,直到程序退出并且泄漏消失。
以下是相关代码sn-ps:
调用此 C++ 代码来加载 COM 对象,pszProgId 是标识目标 DLL 的字符串。
COleDispatchDriver *pDispatchDriver = NULL;
pDispatchDriver = new COleDispatchDriver();
if (!pDispatchDriver->CreateDispatch(pszProgId, &oleException))
{
throw &oleException;
}
pDispatchDriver->m_bAutoRelease = TRUE;
*ppvObject = (void *) pDispatchDriver;
void ** ppvObject 是我们传递的一个指针,用于通常保存不同的对象。它是一个更大的结构的一部分。 这是我们在释放 COM 对象时调用的代码。
在我们使用完 COM 对象后,我们按如下方式释放它:
COleDispatchDriver* pDispatchDriver = (COleDispatchDriver*) (*((LONG_PTR*)(ppvObject)));
pDispatchDriver->ReleaseDispatch();
delete pDispatchDriver;
每次调用都会泄漏大约 1 兆。目标 COM 对象是 C#。任何人都知道我们做错了什么或更好的方法来做我们想做的事情?
我们正在 VisualStudio 2015 中构建它以防万一。
Re xMRi:
如前所述,我们尝试将该标志更改为 TRUE 无效。作为健全性检查,我在阅读您的帖子后再次尝试这样做,但它再次没有解决内存泄漏问题。因此,为了更清楚起见,我更新了我的代码以将其设置为 TRUE,这几乎可以肯定是正确的值,但仍然表现出与上述相同的内存泄漏。
【问题讨论】:
-
C# 代码设计泄漏内存。垃圾收集器在必要时运行,绝不是因为您释放了接口指针。编写一个执行此代码一百万次的单元测试,以确保您的 Release() 调用正常,并验证您是否存在真正的内存泄漏,这将使您的程序崩溃。您可以通过查看 perfview.exe 中的 .NET 内存性能计数器来观察 GC 的作用
-
我们已经运行了 5,000 次迭代,客户端程序的内存增长到大约 5 gig。那时我们不得不杀死它,但我很确定这不仅仅是延迟垃圾收集。
标签: c# c++ memory-leaks com