Need 2 forced garbage collections?????

R

Richard

Hi,

I'm writing an MS Outlook 2000 Addin in C#. I have
created C# classes that monitor folder events and do other
business logic. Things work fine until I want to exit
Outlook. When I exit Outlook I have to force 2 garbage
collection cycles in order for all of my folder monitor
classes to get cleaned up {else Outlook will not unload
from memory}. In other words my OnDisconnect() method
looks something like this:

{
// recursively null out all folder objects
myOutlookMonitor = null;

Trace.Writeln("First GC.Collect()...");

GC.Collect();
GC.WaitForPendingFinalizers();

Trace.Writeln("Second GC.Collect()...");

GC.Collect();
GC.WaitForPendingFinalizers();
}

I put Trace calls into the destructors for my folder
monitor classes and indeed I have confirmed that several
of the destructors do not get called until the second
GC.Collect() is issued...

Does anybody know why I would need to issue 2 GC.Collect()
calls? Outlook does succesfully unload from memory after
I issue the second GC.Collect() and it will NOT unload
from memory unless I issue 2 GC.Collect() calls....

--Richard
 
J

Jeffrey Tan[MSFT]

Hi Richard,

I think when you invoke the first time of garbage collection, some object of
you application still did not get release(its reference count >0), so they
will not
get collect.
Then, in the second time, their reference released, so can be succeeded
collect.

Hope this helps,
Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

--------------------
| Content-Class: urn:content-classes:message
| From: "Richard" <[email protected]>
| Sender: "Richard" <[email protected]>
| Subject: Need 2 forced garbage collections?????
| Date: Tue, 9 Sep 2003 16:16:47 -0700
| Lines: 39
| Message-ID: <[email protected]>
| MIME-Version: 1.0
| Content-Type: text/plain;
| charset="iso-8859-1"
| Content-Transfer-Encoding: 7bit
| X-Newsreader: Microsoft CDO for Windows 2000
| X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4910.0300
| Thread-Index: AcN3KHDYFM6hjJ9CSPS/pDtKXLxUYQ==
| Newsgroups: microsoft.public.dotnet.languages.csharp
| Path: cpmsftngxa06.phx.gbl
| Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.languages.csharp:183617
| NNTP-Posting-Host: TK2MSFTNGXA09 10.40.1.161
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
|
| Hi,
|
| I'm writing an MS Outlook 2000 Addin in C#. I have
| created C# classes that monitor folder events and do other
| business logic. Things work fine until I want to exit
| Outlook. When I exit Outlook I have to force 2 garbage
| collection cycles in order for all of my folder monitor
| classes to get cleaned up {else Outlook will not unload
| from memory}. In other words my OnDisconnect() method
| looks something like this:
|
| {
| // recursively null out all folder objects
| myOutlookMonitor = null;
|
| Trace.Writeln("First GC.Collect()...");
|
| GC.Collect();
| GC.WaitForPendingFinalizers();
|
| Trace.Writeln("Second GC.Collect()...");
|
| GC.Collect();
| GC.WaitForPendingFinalizers();
| }
|
| I put Trace calls into the destructors for my folder
| monitor classes and indeed I have confirmed that several
| of the destructors do not get called until the second
| GC.Collect() is issued...
|
| Does anybody know why I would need to issue 2 GC.Collect()
| calls? Outlook does succesfully unload from memory after
| I issue the second GC.Collect() and it will NOT unload
| from memory unless I issue 2 GC.Collect() calls....
|
| --Richard
|
|
|
 
D

Dave

Any object thtat contains a finalizer (i.e. a destructor) requires at least
two garbage collection cycles. The first cycle detects that it has a
finalizer that must be run and puts the object on a special queue that will
run the finalizer, and the second cycle cleans it up after the finalizer has
run. While the object is on the finalizer queue the object is still
considered reachable.

These articles explain this and many other aspects of GC you should know
about.
http://www.wintellect.com/resources...microsoft.com/msdnmag/issues/1100/GCI/GCI.asp

http://www.wintellect.com/resources...crosoft.com/msdnmag/issues/1200/GCI2/GCI2.asp
 
J

Jay B. Harlow [MVP - Outlook]

Richard,
In case you don't already have it, the following link has a number of
resources on using Outlook with .NET.

http://www.microeye.com/resources/res_outlookvsnet.htm

Also, when you are done with an Outlook object (any COM object really) you
should call System.Runtime.InteropServices.Marshal.ReleaseComObject, rather
than waiting on the GC to do it for you.

Hope this helps
Jay
 
S

Sunny

Hi,

I'm writing an MS Outlook 2000 Addin in C#. I have
created C# classes that monitor folder events and do other
business logic. Things work fine until I want to exit
Outlook. When I exit Outlook I have to force 2 garbage
collection cycles in order for all of my folder monitor
classes to get cleaned up {else Outlook will not unload
from memory}. In other words my OnDisconnect() method
looks something like this:

{
// recursively null out all folder objects
myOutlookMonitor = null;

Trace.Writeln("First GC.Collect()...");

GC.Collect();
GC.WaitForPendingFinalizers();

Trace.Writeln("Second GC.Collect()...");

GC.Collect();
GC.WaitForPendingFinalizers();
}

I put Trace calls into the destructors for my folder
monitor classes and indeed I have confirmed that several
of the destructors do not get called until the second
GC.Collect() is issued...

Does anybody know why I would need to issue 2 GC.Collect()
calls? Outlook does succesfully unload from memory after
I issue the second GC.Collect() and it will NOT unload
from memory unless I issue 2 GC.Collect() calls....

--Richard

Hi Richard,
I had the same problem. So, the way I solved is:
Make a all references to main Outlook objects (like Outlook.Application,
Outlook.Application.Explorers, etc.) public static. And the event
handlers also.
If you have used a private objects, before leaving the method/part of
code where they are created make:
if (outlookobject != null)
{
while (Marshal.ReleaseObjByReference(outlookobject) > 0);
//this is empty, just to release all wrappers
outlookobject = null;
}

You have to do the above also in methods where you receive an outlook
object as parameter (like in event handlers). You have to make
ReleaseObjByReference on the parameter.
The number of references increase with every call from COM environment
to managed class, so you have to be careful.

Hope that helps
Sunny

P.S. There are a lot of posts in .outlook.program_addins and
..developer.outlook.addins about that. In some of the threads me and
other guys have paste some code. You have to search for 'Outlook stays
in memory' and things like that.
 
R

Richard N

Thanx a million!

Both of the articles were excellent. My code suffers from an
unavoidable case of resurrection...

--Richard
 

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