开发者

Outlook 2007 Add-in Memory Leak?

I've created a simple Outlook 2007 add-in using C# which loops through a selection of Messages and examines their attachments.

I'm running this add-in on a set of ~25,000 selected Messages. Immediately, however, I notice the memory usage of Outlook (seen via perfmon) shooting up. After running the add-in in debug mode, line-by-line, it is apparent that memory is assigned to Outlook upon the first instance of accessing a Message's Attachments collection. This memory is never returned to the system; Outlook continues to eat memory until it hits ~1GB (after about 12,000 Messages), whereupon I receive an "out of memory or system resources" error. Any ideas?

Here's part of the code:

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

            //Only process if Item i开发者_JAVA技巧s 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();
        }            


Are you using a foreach loop for processing the attachments (that part is left out in your code snippet)?

According to a blog post foreach causes a memory leak whereas for does not:

OOM.NET: Part 2 - Outlook Item Leaks

Apparently there is also a Hotfix available fixing various issues regarding memory leaks.

UPDATE

Have you tried freeing each single attachment contained in the attachments collection?

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

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


If nothing else I'd check the Msg object for attachments first before calling this line:

 Outlook.Attachments objAttachments = Msg.Attachments;

otherwise you're allocating for each and every message, regardless of presence of attachment... so if there are only 5,000 messages with attachments, that should be done only 5,000 times instead of all ~25,000 times


Did you try to check that Marshal.ReleaseComObject() always return 0 maybe you have additional references somewhere?

Moreover did you find any Dispose items. Then you should call Dispose()


I seem to have solved the issue. Since objSelectedItems was brought in via Applicaiton.ActiveExplorer().Selection, I did the following:

  1. Copy each Object in objSelectedItems into a locally declared List.
  2. Call Marshal.ReleaseComObject(objSelectedItems).
  3. Begin my loop as posted in the Question above - though modified to use the local Object List instead of the Outlook Selection.

This apparently means that, for some reason, the Selection had to be released before the individual objects within it could be released.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜