2015-04-30 27 views
2

我的.NET應用程序在很短的時間內使用非常多的RCW(數千個RCW在不到一秒內)。我能夠衡量這一行爲具有以下性能計數器: - 過程 - >句柄計數 - .NET CLR內存 - >使用的水槽塊的#使用GC.AddMemoryPressure觸發更頻繁的Runtime Callable Wrapper(RCW)最終化是否合適?

我們正確實施各地的RCW IDisposable的包裝對象;我們在各種RCW上以適當的順序調用Marshal.FinalReleaseComObject。

根據this blog post,RCW底層的COM對象實際上並沒有清理完畢,直到RCW完成。

使用GC.AddMemoryPressure來強制GC更快地清理我們的RCW以防止內存不足錯誤是否合適?

+0

這是不恰當的,你沒有一個很好的方法來調用RemoveMemoryPressure() 。這需要一個終結器,一個RCW已經有一個,你不能修改它。如果你確信你正確地調用了FRCO,那麼你只需要更快處理:) –

+0

Hans,我們將每個RCW都包裝在我們自己的C#對象中,每個對象都有一個析構函數。在我們的C#包裝器對象中增加內存壓力是否合適?當然,我們也實現Dispose,它調用Marshal.FinalReleaseComObject。由於我們有一個析構函數,我們可以消除內存壓力。 –

+1

如果您確信您正確地給FRCO打電話,那麼您不應該耗盡內存,也不需要GC的幫助。當你實際上內存不足時,你只能得到OOM,使用AddMemoryPress不會停止。如果你不確信,你不應該這樣做,那麼你最好引用計數你創建的對象並調用GC.Collect ()在一定的值。 –

回答

2

您應該維護對每個COM對象的顯式管理引用,並且在不再需要COM對象時立即調用Marshal.ReleaseComObject

此方法用於顯式控制從託管代碼使用的COM對象的生命週期。您應該使用此方法及時釋放保留對資源引用的基礎COM對象,或者必須按特定順序釋放對象。

請注意,使用「雙點」會導致運行時創建隱藏的託管引用,例如, Excel中的常見模式:

Worksheet sheet = excelApp.Worksheets.Open(sheetName); 

創建一個包裝工作表的隱藏託管對象。首選的方法是

Worksheets sheets = excelApp.Worksheets; 
Worksheet sheet = sheets.Open(sheetName); 

你會調用Marshal.ReleaseComObject的每個那些管理變量,在創建它們的順序相反。

如果你有COM對象隱藏引用,唯一可靠的方法來處理他們,我看到的是

GC.Collect(); 
GC.WaitForPendingFinalizers(); 
+0

謝謝,埃裏克。正如我上面所說,我們已經使用Marshal.ReleaseComObject。而且我們對「雙點」小心 - 即我們確保釋放每個管理參考。我們也知道GC.Collect + GC.WaitForPendingFinalizers會清除它們。但我的問題是在這種情況下使用GC.AddMemoryPressure是否合適,這樣我們就不必手動調用GC.Collect + GC。WaitForPendingFinalizers。 –

相關問題