0

在 C++ 未损坏的项目中,外部 (*) 托管 DLL 通过COM 可调用包装器 (CCW)使用(向 RegAsm 注册)。但是存在内存泄漏:托管内存从未清理过。

背景:C++ 项目是一个古老的 32 位程序。它加载了几个 DLL,其中一些是托管 DLL(用 C# 编写)。

在一个最小的例子中,.Net DLL 工作正常。也许 GC 对以不同方式使用托管代码感到困惑?

如何强制 CCW 的垃圾收集?

现有 Wrapper 中的以下代码不起作用:

    __declspec(dllexport) void ExecuteCcwGcWrapper(void* ComObject)
    {
        IntPtr ptr(ComObject);
        Object^  obj = System::Runtime::InteropServices::Marshal::GetObjectForIUnknown(ptr);
        try {
            System::Runtime::InteropServices::Marshal::FinalReleaseComObject(obj);
        }
        catch (ArgumentException^ e) {
            System::Diagnostics::Debug::WriteLine(e->Message);
        }
        catch (ArgumentNullException^ e) {
            System::Diagnostics::Debug::WriteLine(e->Message);
        }
        catch (Exception^ e) {
            System::Diagnostics::Debug::WriteLine(e->Message);
        }
    }

“FinalReleaseComObject”中的 ArgumentException -> 没有 COM 对象。在调试器中,对象“obj”看起来不错。结构、数据,一切OK。

以下代码将运行,但不起作用:

    __declspec(dllexport) void ExecuteCcwGcWrapper(void* ComObject)
    {
        IntPtr ptr(ComObject);
        while (System::Runtime::InteropServices::Marshal::Release(ptr) > 0);
        //System::GC::AddMemoryPressure(0x7FFFFFFF);
        System::GC::Collect();
        //System::GC::WaitForFullGCComplete();
        System::GC::WaitForPendingFinalizers();
    }

(*我无权访问源代码)

4

1 回答 1

0

正如德国论坛CCW GC 中所讨论的那样

System::GC::Collect(System::GC::MaxGeneration, System::GCCollectionMode::Forced, true);
System::GC::WaitForPendingFinalizers();
System::GC::Collect(System::GC::MaxGeneration, System::GCCollectionMode::Forced, true);

会成功的。

污垢解决方案:GC::GetTotalMemory

于 2017-09-19T05:47:12.167 回答