I have a MDI program in which user can open different document and edit it. After several user use it, they report that it becomes more and more slow. So I watch the memory usage of it carefully and found a problem : it seems the memory is never released after a document is closed. I watch the memory cost in Tesk Manager, and found that whenever a document is opened, the memory cost increases. However, after the document is closed, the memory cost does not drop. When another document is opened, it cost more memory.
I later realize that since the document is opened for a while, the objects it allocated have been moved to Generation 2. So even if I close the document, the memory will not be free.
After I add "GC.Collect()" in the document close event, the memory cost looks normal : it decrease after the document is closed. However, the GC.Collect() is not recommand in SDK document. Is it safe to call it after each document closes
Thanks!

A Question on GC
Robin Lundgren
Looks Ok, but you still did not tell me what these documents are and how you are opening them and closing them Are these file handles If so, are you calling Dispose() when you close the documents
If you have followed all recommended best practices and still, GC.Collect() is required then I guess you have a special case and you can go ahead with using it.
Regards,
Vikram
neuroma
The Unknown 7
I understand that GC tries to do the minimum amount of work necessary, but it make the diagnosis hard. For example : I'd like to detect memory cost change during the document open/close circle in my program, so I add calls to GC.GetTotalMemory in several place in my code. However, these calls always returns the same value and I have no way to detect that if my memory has released. Is there a way to force a truely full GC
Thanks!
Lei Jiang
Bulldog.NET
Besides, this is a common usage in document-center application : open a document, edit it, close it; open another document, and do the same; etc. If the full GC never get called, the momory will cost more and more. Is calling GC.Collect() in my code the only solution
Thanks!
VMan
Thanks!
JeffOzvold
meilon
When you call GC.Collect() it forces Garbage Collection. Since the Garbage Collection process as such is an expensive process, it adds a performance hit your application.
There should be an correct way to stop those memory leaks, What are these documents that you are using, how are you opening and closing them Please provide more details.
Regards,
Vikram
JamieWP
Yes, I have called Dispose() when close the document, and in the Dispose override of each type of document, all unmanaged resource are released.
I beleive all the resource are released since when I call the GC.Collect(), the memory drop dramatically, finally reach the memory size at the program startup.
What's I am curious is why the full GC not get called automatically for me in this situation.
Thanks!
jmccall3
Calling GC.Collect() is your best bet to force a full collection, but know that in doing so you will be promoting all live objects a generation, which in turn will keep objects in memory longer (in fact, it will keep entire object graphs in memory longer if the promoted objects contain references to younger live objects).
-Chris
TobyKraft
sethgold
To answer your questions:
1) There are many situations that trigger a collection. These include (but are not limited to): when an allocation fails due to insufficent memory, when generation 0's budget is exceeded, if memory pressure hits a threshold, etc.
2) Yes, it is a GC request. Since full collections are expensive perf-wise, the GC tries to do the minimum amount of work necessary.
If you're seeing performance issues, I recommend reading Rico's blog (http://blogs.msdn.com/ricom/), which has some great recommendations on when it's ok to call GC.Collect (in your case, after a document is closed *may( be an appropriate time to call Collect).
Also, Maoni has some good GC information on her blog: http://blogs.msdn.com/maoni/
And of course, take a look at my blog for more information about GC and Dispose:
http://blogs.msdn.com/clyon/
Hope that helps
-Chris
jklegseth
If you can manage with the performance hit that happens with the call to GC.Collect(), then you can go ahead with using it.
Regards,
Vikram
Glen Plantz
Yes, I have removed that GC.Collect() line from my code since I notice that when the memory cost is over 600MB, a collection will be triggered.
But I still have some question :
1) In which exact situation the collection will be triggered I have a large program, I found it will trigger GC when the cost is over 600MB; and a small program in which GC will be triggered when the cost is over 100MB (both program runs in the same machine).
2) It seems it's not a full GC. For that large program, when the memory cost is over 600MB, after GC it will not drop to the initial 20MB ( the actual memory size it cost), but about 400MB. It seems it's not a full GC, but it's really a full GC request.
Thanks!
AlsoDave
Since your objects reach generation 2, they won't be collected unless a full GC occurs. Since a full collection can be very expensive, the GC will not run them as frequently as it will collect Gen 0 objects. However, you don't have a memory leak. If your machine starts to run low enough on resources, the GC will eventually determine that the cost of running a full collection is worth it, and your objects will be collected. You don't have to call Collect yourself in order to clean those up.
-Shawn