2009-10-15 77 views
3

我已經使用C#創建了一個簡單的Outlook 2007加載項,它通過選擇消息循環並檢查其附件。Outlook 2007加載項內存泄漏?

我在一組〜25,000選定的消息上運行此加載項。不過,我立即注意到Outlook的內存使用情況(通過perfmon看到)正在上升。在逐行調試模式下運行加載項後,顯然在訪問Message's Attachments集合的第一個實例時將內存分配給Outlook。這個內存是從來沒有返回給系統; Outlook在大約1GB(大約12,000條消息)之後繼續佔用內存,於是我收到「內存不足或系統資源」錯誤。有任何想法嗎?

下面是部分代碼:

 for(int i = 1; i <= objSelectedItems.Count; i++) 
     { 
      Object objMsg = objSelectedItems[i]; 

      //Only process if Item is a Message 
      if (objMsg is Outlook.MailItem) 
      { 
       Outlook.MailItem Msg = objMsg as Outlook.MailItem; 

       //The culprit: this allocates memory to Outlook which I can't get back 
       Outlook.Attachments objAttachments = Msg.Attachments; 

       //Perform some actual work here// 

       //Clean up Outlook objects; does not appear to give memory back to system 
       Msg.Close(Microsoft.Office.Interop.Outlook.OlInspectorClose.olDiscard); 
       Marshal.ReleaseComObject(objAttachments); 
       Marshal.ReleaseComObject(Msg); 
      } 

      Marshal.ReleaseComObject(objMsg); 
      GC.Collect(); 
      GC.WaitForPendingFinalizers(); 
     }    
+0

該修復程序是否解決了您的問題?也許你需要釋放每一個附件(見我的更新)? – 2009-10-15 22:00:49

回答

0

我似乎已經解決了這個問題。由於objSelectedItems經Applicaiton.ActiveExplorer()的選擇帶來了,我做了以下內容:

  1. 複製每個對象objSelectedItems成局部聲明的列表。
  2. 調用Marshal.ReleaseComObject(objSelectedItems)。
  3. 開始我的循環發佈上述問題 - 雖然修改爲使用本地對象列表,而不是Outlook選擇。

這顯然意味着,出於某種原因,選擇必須在其中的各個對象被釋放之前被釋放。

0

如果不出意外我會先調用此行之前檢查附件的消息對象:

Outlook.Attachments objAttachments = Msg.Attachments; 

否則你分配爲每每封郵件,無論附件是否存在......所以如果只有5000條帶附件的郵件,應該只做5000次而不是全部〜25,000次

+0

這樣的條件,如'if(Msg.Attachments.Count> 0){}',也會導致分配相同數量的內存。 – NickL 2009-10-15 17:02:41

2

您是否使用foreach循環來處理附件(該部分在您的代碼片段中遺漏了)?

根據博客文章foreach導致內存泄漏而for並不:

OOM.NET: Part 2 - Outlook Item Leaks

顯然還存在有關內存泄漏Hotfix提供固定的各種問題。

UPDATE

你試過釋放包含在附件集合中的每個單獨的附件?

for (int i = 1; i <= oAttachs.Count; i++) 
{ 
    Outlook.Attachment oAttach = oAttachs[i]; 

    // Do nothing with attachment 
    Marshal.ReleaseCOMObject(oAttach); 
    oAttach = null; 
} 
+0

今天早上我使用了一個foreach,但是我今天早些時候偶然發現了這個OOM.NET文章,並將我的代碼更改爲上面看到的for循環,但沒有任何效果。我只是開始尋找你發佈的修補程序... – NickL 2009-10-15 17:10:51

+0

因此,與foreach不是原因。無論如何,OOM似乎有點棘手。您是否嘗試在發佈代碼時運行代碼(即,沒有「//執行您在此處的某些實際工作」部分)?這仍然有內存泄漏?否則,問題可能在代碼的特定部分(無論如何,我會嘗試評論代碼的某些部分,直到內存泄漏消失;調試器可能不會在代碼中顯示正確的位置)。 – 2009-10-15 17:40:59

+0

是的,我發佈的代碼實際上就是我正在運行的代碼。我已經實施了「實際工作」代碼,但暫時被註釋掉了。罪魁禍首絕對是我第一次訪問Msg.Attachments的那一行(不管是我的示例中的新對象的分配,還是一個簡單的檢查條件,比如Msg.Attachments.Count)。沒有這條線,我沒有問題(但是,當然,也無法訪問附件)。 – NickL 2009-10-15 17:48:44

0

你是否試圖檢查Marshal.ReleaseComObject()總是返回0也許你有其他的引用?

此外,您是否找到任何Dispose項目。那麼你應該打電話給Dispose()

+0

我剛剛調查了這個建議 - 我對Marshal.ReleaseComObject()的調用總是返回爲<= 0,我認爲這是OK。 – NickL 2009-10-15 17:03:43