簡體   English   中英

使用COM和C#的多線程應用程序中的內存泄漏

[英]Memory leaks in a multi-threaded application using COM & C#

我編寫了一個多線程非托管應用程序,該應用程序在其工作線程中使用COM對象。 一切順利,直到我開始使用導出為COM的.NET對象來完成工作。

試着玩弄代碼並注釋掉.NET對象功能的某些部分,我設法將其固定為.NET對象中COM對象的用法。 總結一下:

  1. 我的程序啟動了幾個工作線程。
  2. 每個工作線程都會初始化一個基於.NET的COM對象來完成工作。
  3. 基於.NET的COM對象在內部使用非托管COM對象。

令我驚訝的是,直到OutOfMemory異常開始出現之前,應用程序的內存消耗開始穩定增長。

這是我的.NET實現:

void DoSomeWork()
{
    IComObject O = new ComObjectClass();
    try
    {
        // do something
    }
    finally
    {
        Marshal.ReleaseComObject(O);
    }

}

如果我注釋掉此功能,內存泄漏將消失。 如果我在其中調用GC.Collect(),則仍然會發生內存泄漏。

關於可能發生的事情有什么想法嗎?

編輯:基於注釋和答案的更多信息:

  1. 創建的所有線程都在MTA中運行。
  2. 所有COM對象都實現IMarshal並使用自由線程封送處理程序。
  3. 做什么是無關緊要的-即使是int i = 0; i ++; 產生泄漏。
  4. ComObjetClass記錄的對象是舊的並且經過測試。 這並不意味着它沒有問題,但並不刺眼。
  5. 我嘗試通過C#程序在主線程上以及另一個創建的線程上反復創建COM對象。 在這兩種情況下,內存泄漏都消失了。 從非托管代碼到托管代碼的交叉似乎又是至關重要的。 刪除其中的任何部分都會導致問題消失。

可能是您的COM包裝對象需要切換到STA線程才能完成。 如果您的STA不發送消息,則將永遠不會發生,因此將不會調用finalize,這反過來會導致內存泄漏。

此KB中有更多信息。

您好建議您使用以下代碼。

     if (feature != null) 
        { 
            while (Marshal.ReleaseComObject(feature) > 0) 
            { }
            feature=null;
        }

如果您使用com對象作為引用類型。 恩。 光標。 如果您只是在做Marshal.ReleaseComObject(O);

比僅釋放一個引用要多,其余的引用將保留在內存中,因此最好釋放所有引用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM