Force CCW Garbge Collection

В неповрежденном проекте C++ внешняя (*) управляемая DLL используется через COM Callable Wrapper (CCW) (зарегистрированный в RegAsm). Но есть утечка памяти: управляемая память никогда не очищалась.

Предыстория: проект C++ - это старая 32-битная программа. Он загружает несколько библиотек DLL, некоторые из них являются управляемыми библиотеками (написанными на C#).

В минимальном примере.Net DLL работает нормально. Может быть, GC запутался с использованием управляемого кода различными способами?

Как заставить сборщик мусора против часовой стрелки?

Следующий код в существующем 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);
        }
    }

ArgumentException в "FinalReleaseComObject" -> Нет COM-объекта. В отладчике объект "obj" выглядит нормально. Структура, данные, все ок.

Следующий код будет работать, но не будет иметь никакого эффекта:

    __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();
    }

(* У меня нет доступа к источникам)

1 ответ

Как обсуждалось на немецком форуме 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.

Другие вопросы по тегам