2017-09-18 41 views
0

在C++ unmamaged項目中,通過COM Callable Wrapper (CCW)(使用RegAsm註冊)使用外部(*)受管D​​LL。但是存在內存泄漏:管理內存從未被清理。強制CCW Garbge集合

背景:C++項目是一個老式的32位程序。它加載了幾個DLL,其中一些是被管理的DLL(用C#編寫)。

在一個最小的例子中.Net DLL工作正常。也許GC對於以不同方式使用託管代碼感到困惑?

如何強制CCW垃圾回收?

在現有的包裝下面的代碼沒有工作:

__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」看起來很好。結構,數據,一切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(); 
    } 

(*我沒有訪問源)

+0

Hmya,一個程序員的「內存泄漏」是另一個程序員的功能。 GC在認爲有必要時收集這些信息,這不是那種認爲經常需要它的運行時環境。這使得'使用'和Dispose()更加重要。觀察Perfmon.exe中的收集計數器以獲取土地的位置。並且請記住,Marshal.FinalReleaseComObject()是非常危險的,你可以很容易地自殺和摧毀對象,而你仍然有一個接口指針。搖晃的指針是可以診斷的令人討厭的錯誤。 –

回答

0

如在德國論壇CCW GC did not work討論:

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