简体   繁体   English

Outlook 2007加载项内存泄漏?

[英]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. 我使用C#创建了一个简单的Outlook 2007加载项,它循环选择了一些消息并检查它们的附件。

I'm running this add-in on a set of ~25,000 selected Messages. 我在一组约25,000个选定的消息上运行此加载项。 Immediately, however, I notice the memory usage of Outlook (seen via perfmon) shooting up. 但是,我立即注意到Outlook(通过perfmon看到)的内存使用情况。 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. 在逐行调试模式下运行加载项之后,显然在访问Message的Attachments集合的第一个实例时将内存分配给Outlook。 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. Outlook继续占用内存,直到它达到~1GB(大约12,000条消息之后),于是我收到“内存不足或系统资源”错误。 Any ideas? 有任何想法吗?

Here's part of the code: 这是代码的一部分:

        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();
        }            

Are you using a foreach loop for processing the attachments (that part is left out in your code snippet)? 您是否使用foreach循环来处理附件(该部分在代码片段中省略)?

According to a blog post foreach causes a memory leak whereas for does not: 根据博客中foreach导致内存泄漏,而for不:

OOM.NET: Part 2 - Outlook Item Leaks OOM.NET:第2部分 - Outlook项目泄漏

Apparently there is also a Hotfix available fixing various issues regarding memory leaks. 显然,还有一个修补程序可用于修复有关内存泄漏的各种问题。

UPDATE 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: 如果没有其他我在调用此行之前先检查Msg对象的附件:

 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 否则你要为每条消息分配,无论附件是否存在......所以如果只有5,000封带附件的消息,则应该只进行5,000次而不是全部~25,000次

Did you try to check that Marshal.ReleaseComObject() always return 0 maybe you have additional references somewhere? 您是否尝试检查Marshal.ReleaseComObject()始终返回0可能您在某处有其他参考?

Moreover did you find any Dispose items. 此外,你找到任何Dispose项目。 Then you should call Dispose() 然后你应该调用Dispose()

I seem to have solved the issue. 我好像已经解决了这个问题。 Since objSelectedItems was brought in via Applicaiton.ActiveExplorer().Selection, I did the following: 由于objSelectedItems是通过Applicaiton.ActiveExplorer()。选择引入的,我做了以下内容:

  1. Copy each Object in objSelectedItems into a locally declared List. 将objSelectedItems中的每个Object复制到本地声明的List中。
  2. Call Marshal.ReleaseComObject(objSelectedItems). 调用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. 开始我在上面的问题中发布的循环 - 虽然修改为使用本地对象列表而不是Outlook选择。

This apparently means that, for some reason, the Selection had to be released before the individual objects within it could be released. 这显然意味着,出于某种原因,必须在其中的各个对象被释放之前释放选择。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM