Garbage collector
-
Application Type: C# Windows Application This application generates multiple reports in batch. For each report requested in the batch, main process spawn threads. Each thread connects to database gets DataSet and Invoke a method to attach ReportDocument with the CrystalReportViewer. Now after threads complete execution, result is multiple reports. Even after I close all reports, I don't see the Mem Usage coming down. This looks like to be an issue with memory taken during the execution of threads. Can somebody suggest what should be done for fast memory recovery :confused: Thanks Ruchi
-
Application Type: C# Windows Application This application generates multiple reports in batch. For each report requested in the batch, main process spawn threads. Each thread connects to database gets DataSet and Invoke a method to attach ReportDocument with the CrystalReportViewer. Now after threads complete execution, result is multiple reports. Even after I close all reports, I don't see the Mem Usage coming down. This looks like to be an issue with memory taken during the execution of threads. Can somebody suggest what should be done for fast memory recovery :confused: Thanks Ruchi
try
GC.Collect();
-
Application Type: C# Windows Application This application generates multiple reports in batch. For each report requested in the batch, main process spawn threads. Each thread connects to database gets DataSet and Invoke a method to attach ReportDocument with the CrystalReportViewer. Now after threads complete execution, result is multiple reports. Even after I close all reports, I don't see the Mem Usage coming down. This looks like to be an issue with memory taken during the execution of threads. Can somebody suggest what should be done for fast memory recovery :confused: Thanks Ruchi
Search your code for the instanciation of objects of classes that implement the
IDisposable
interface. Most of this classes allocate unmanaged resources that are freed by calling theirDispose
method, but not when they are collected by the GC. I learned about that recently by reading a posting from Heath. Here is the linke towards our small conversation: http://www.codeproject.com/script/comments/forums.asp?msg=798736&forumid=1649#xx798384xx -
Search your code for the instanciation of objects of classes that implement the
IDisposable
interface. Most of this classes allocate unmanaged resources that are freed by calling theirDispose
method, but not when they are collected by the GC. I learned about that recently by reading a posting from Heath. Here is the linke towards our small conversation: http://www.codeproject.com/script/comments/forums.asp?msg=798736&forumid=1649#xx798384xxTroschi wrote: Most of this classes allocate unmanaged resources that are freed by calling their Dispose method, but not when they are collected by the GC. If they're not freed at all, that's a bug in the class. Classes that allocate unmanaged resources should implement a finalizer (using the 'destructor' syntax in C#,
~ClassName
) which frees the resources. Finalizers have a few problems in the current releases of the Framework. Firstly, the memory is only released on the second collection that hits this object. The first GC detects there are no references to this object and that it has a finalizer, so it puts the object on a finalization queue. A thread that's reserved only for calling finalizers reads this queue and calls the finalizer for each object. Once the finalizer has run, it removes the reference. The next time the GC runs for the appropriate generation (the object is considered to have survived the original collection and is promoted to the older generation) the memory will then be freed. If you're writing your own classes, you should callGC.SuppressFinalize
in yourDispose
method to indicate that the object no longer requires finalization. This saves the object surviving unnecessarily. You should still callDispose
(or use ausing
block) to avoid the unnecessary memory pressure caused by the implementation of finalization. Consider the finalizer to be a back-stop against failing to callDispose
. Stability. What an interesting concept. -- Chris Maunder -
Troschi wrote: Most of this classes allocate unmanaged resources that are freed by calling their Dispose method, but not when they are collected by the GC. If they're not freed at all, that's a bug in the class. Classes that allocate unmanaged resources should implement a finalizer (using the 'destructor' syntax in C#,
~ClassName
) which frees the resources. Finalizers have a few problems in the current releases of the Framework. Firstly, the memory is only released on the second collection that hits this object. The first GC detects there are no references to this object and that it has a finalizer, so it puts the object on a finalization queue. A thread that's reserved only for calling finalizers reads this queue and calls the finalizer for each object. Once the finalizer has run, it removes the reference. The next time the GC runs for the appropriate generation (the object is considered to have survived the original collection and is promoted to the older generation) the memory will then be freed. If you're writing your own classes, you should callGC.SuppressFinalize
in yourDispose
method to indicate that the object no longer requires finalization. This saves the object surviving unnecessarily. You should still callDispose
(or use ausing
block) to avoid the unnecessary memory pressure caused by the implementation of finalization. Consider the finalizer to be a back-stop against failing to callDispose
. Stability. What an interesting concept. -- Chris MaunderThanks for this explanation. I think i got the idea. But let's go back to the pactual roblem this thread is about. Today, i found a similar problem in my application. I have an
ArrayList
where i store instances of a certain class X. Each of this instances possesses aQueue
that is pretty big. For example, if i add 2 instances of class X to the ArrayList the memory usage increases by 4MB. When i remove the instances from the ArrayList, they are collected by GC (tested that) but the memory usage doesn't decrease. But also it doesn't increase when i add two new instances of class X to the ArrayList. Only a third object increases memory usage. Could it be that the memory is freed when the instances of class X are collected by GC but somehow remains attached to my application?