【问题标题】:Using COleDispatchDriver to dynamically load COM object leaking memory使用 COleDispatchDriver 动态加载 COM 对象泄漏内存
【发布时间】: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


【解决方案1】:

如果您将m_bAutoRelease 设置为 FALSE,ReleaseDispatch 不会执行任何操作。所以实际上你并没有释放这个 COM 对象的实例。

查看实现:

void COleDispatchDriver::ReleaseDispatch()
{
    if (m_lpDispatch != NULL)
    {
        if (m_bAutoRelease)
            m_lpDispatch->Release();
        m_lpDispatch = NULL;
    }
}

因此在将m_bAutoRelease 设置为FALSE 时产生了问题。检查您这样做的原因。

你可以直接获取LPDISPTACH指针并调用Release(),但这正是m_bAutoReleaseTRUE时应该做的。

【讨论】:

    猜你喜欢
    • 2011-06-17
    • 2012-12-13
    • 2013-04-28
    • 1970-01-01
    • 1970-01-01
    • 2012-05-20
    • 2023-03-25
    • 2012-10-31
    • 1970-01-01
    相关资源
    最近更新 更多