Out of memory errors during operation that processes all messages

2

280Z28

Using Outlook 2007

In response to a custom menu item being clicked, I have a BackgroundWorker
start processing messages in a MAPIFolder.

While it is in the following loop, I get messages from Outlook saying an
add-in (NOD32) has been disabled due to an out-of-memory condition, and to .
There are 731 items in the folder it is processing, and it appears to give
the error about ~200 in. The error appears in Outlook when I step over the
marked line. I've included many extra details in that comment.

int FixDatesForFolder( Outlook.MAPIFolder folder, bool subfolders )
{
// NOTE: problem occurs even if subfolders is false
int count = 0;

foreach ( object item in folder.Items )
{
if ( !(item is Outlook.MailItem) )
continue;

Outlook.MailItem mailItem = (Outlook.MailItem)item;

// check the date range
// ***********************
// Outlook shows error about NOD32 being disabled while trying to
step
// into the following line. When this if statement is commented out,
// no error is given, but this function won't be able to operate
properly
// without this check. Also, when this statement is commented out
**and I
// have subfolders set to true**, memory usage in Outlook grows so
it is
// using 190MB by the time this function returns from processing
around
// 25,000 items. Memory seems to be freed not when the function
returns,
// but rather when when I close Outlook. I have 2GB of memory, and
in the
// worst case at least 800MB was free according to task manager, so
I
// don't know why I'm seeing Out-Of-Memory errors.
if ( !IsDateInRange( mailItem.ReceivedTime ) )
continue;

// fix the received date
FixDatesForItem( mailItem );
count++;
} while ( enumerator.MoveNext( ) );

if ( subfolders )
{
foreach ( Outlook.MAPIFolder sub in folder.Folders )
{
count += FixDatesForFolder( sub, true );
}
}

return count;
}

bool IsDateInRange( DateTime date )
{
// These are private class variables declared as follows
// DateTime beginDate = new DateTime( 2006, 4, 30, 18, 0, 0 );
// DateTime endDate = new DateTime( 2006, 5, 1, 2, 0, 0 );

return (date >= beginDate) && (date <= endDate);
}

void FixDatesForItem( Outlook.MailItem item )
{
// empty for now
}
 
2

280Z28

There seems to be an intense handle leak in the interop layer. After simply
checking the UnRead property of a couple hundred MailItem objects in my
MailFolder.ItemAdd handler, there are 6000+ handles open by Outlook.
SysInternals ProcessExplorer shows the handles are unnamed Event handles.
 
K

Ken Slovak - [MVP - Outlook]

Try setting all your objects to Nothing or null values or releasing them
each time through a loop. You may also have to explicitly call the garbage
collector.
 
2

280Z28

The problem can be repeated with something so simple as this:

void JunkItems_ItemAdd( object Item )
{
if ( !(Item is Outlook.MailItem) )
return;

Outlook.MailItem mailItem = (Outlook.MailItem)Item;
mailItem.UnRead = false;
}

If I take that code and add the following two lines to the end of it, the
exact same problem occurs:

mailItem = null;
Item = null;

If I take add a counter and call the following code after 100 times through
this function, the extra ~2000 handles that were created are cleaned up.
However, JunkItems_ItemAdd no longer seems to be connected; it is never
called again. :(

if ( itemsAddedSinceGc > 100 )
{
itemsAddedSinceGc = 0;
System.GC.Collect();
}
 
K

Ken Slovak - [MVP - Outlook]

So it is a garbage collection problem, as I suspected.

If your event handler is not being called it's being garbage collected too.
Make sure to add your handler to a hashtable or collection or something to
keep a reference to it alive so it doesn't get garbage collected.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top