none
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced) – doesn`t work? Values in Task Manager. RRS feed

  • Question

  • Hi

    I have created simple WinForms application on .NET 3.5, tested on Win XP SP3.
    There is only one Form class with private variable

    private List<MyClass> _list;

    1. I run my application and I see in Task Manager that Mem Usage for my application is about 10 MB.

    2. I click button to execute this code:

    private void btnAllocateMemory_Click(object sender, EventArgs e)
    
    {
    
    	_list = new List<MyClass>();
    
    	for (int i = 0; i < 10000000; i++)
    
    	{
    
    	_list.Add(new MyClass(i, i.ToString()));
    
    	}
    
    }
    
    

    After this execution Mem Usage of my app grows in Task Manager to about 560 MB.


    3. Then I click next button to set to null private list:

    private void btnSetNull_Click(object sender, EventArgs e)
    
    {
    
     _list = null;
    
    }
    
    

    Nothing is changed in Task Manager (it is ok).

    4. Then I click next button to call collect method:

    private void btnGCcollect_Click(object sender, EventArgs e)
    
    {
    
    GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
    
    }
    
    

    Mem Usage in Task Manager goes down to 25 MB.

    Here is my first question: Where did I lose 15 MB?

    After running my application had only 10 MB, I set list to null and called GC so I thought that it should be again something about 10 MB.

    5. If I minimize now my application I see in Task Manager Mem Usage less than 1 MB !
    6. If I maximize now my application I see in Task Manager Mem Usage about 2.5 MB !

    Here is my second question: what is going on points 5 and 6? I don`t understand this at all. After running my application was 10 MB and now it is only 2.5 MB. How is it possible?

    Regards

    Wednesday, July 14, 2010 2:20 PM

Answers

  • About your 1st question:

    i dont think you need to call GC.Collect method because GC automatically calls it to collect the memory (unused object). If GC was not able to collect memory then there is no more memory you will get when you call it forcefully.

     

    You may check the memory leak - the chances of leak if you are using unmanaged resources in your application:

    To check memory leak follow below steps - you can also refer http://msdn.microsoft.com/en-us/magazine/cc163491.aspx for more detail.

     

    Checking for Leaks
    There are a number of telltale signs that an application is leaking memory. Maybe it's throwing an OutOfMemoryException. Maybe its responsiveness is growing very sluggish because it started swapping virtual memory to disk. Maybe memory use is gradually (or not so gradually) increasing in Task Manager. When a memory leak is suspected, you must first determine what kind of memory is leaking, as that will allow you to focus your debugging efforts in the correct area. Use PerfMon to examine the following performance counters for the application: Process/Private Bytes, .NET CLR Memory/# Bytes in All Heaps, and .NET CLR LocksAndThreads/# of current logical Threads. The Process/Private Bytes counter reports all memory that is exclusively allocated for a process and can't be shared with other processes on the system. The .NET CLR Memory/# Bytes in All Heaps counter reports the combined total size of the Gen0, Gen1, Gen2, and large object heaps. The .NET CLR LocksAndThreads/# of current logical Threads counter reports the number of logical threads in an AppDomain. If an application's logical thread count is increasing unexpectedly, thread stacks are leaking. If Private Bytes is increasing, but # Bytes in All Heaps remains stable, unmanaged memory is leaking. If both counters are increasing, memory in the managed heaps is building up.

     

     


    Please mark the response as answers if it solves your question or vote as helpful if you find it helpful. My Blog: http://ashishkhandelwal.arkutil.com
    • Proposed as answer by Ashish Khandelwal Thursday, July 15, 2010 7:06 AM
    • Marked as answer by kicaj Thursday, July 15, 2010 8:30 AM
    Thursday, July 15, 2010 7:06 AM

All replies

  • Here it is very well explained about the question you asked:

    http://www.itwriting.com/dotnetmem.php

     

    Hope this will help you....


    Please mark the response as answers if it solves your question or vote as helpful if you find it helpful. My Blog: http://ashishkhandelwal.arkutil.com
    Wednesday, July 14, 2010 5:45 PM
  • It was really good article – thank you very much.

    I still have two questions:


    1.After one week of working my another application sometimes slows down because I think
    it allocates memory on page file (swap). Is it possible that GC does not collect not used objects (my app doesn`t have reference to them) and doesn`t remove them from memory because there is free memory on page file (swap)?
    I don`t want use page file (swap) because it is slow – I want remove not used objects from memory and avoid using page file (swap).

    If answer is YES then could I call

    GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);

    to force GC to remove not used objects from memory ?

    If answer is NO does it mean that I have memory leak in my app?

    2. How can I check how much memory of my application is from page file (swap)?

     

    Regards

    Thursday, July 15, 2010 6:52 AM
  • About your 1st question:

    i dont think you need to call GC.Collect method because GC automatically calls it to collect the memory (unused object). If GC was not able to collect memory then there is no more memory you will get when you call it forcefully.

     

    You may check the memory leak - the chances of leak if you are using unmanaged resources in your application:

    To check memory leak follow below steps - you can also refer http://msdn.microsoft.com/en-us/magazine/cc163491.aspx for more detail.

     

    Checking for Leaks
    There are a number of telltale signs that an application is leaking memory. Maybe it's throwing an OutOfMemoryException. Maybe its responsiveness is growing very sluggish because it started swapping virtual memory to disk. Maybe memory use is gradually (or not so gradually) increasing in Task Manager. When a memory leak is suspected, you must first determine what kind of memory is leaking, as that will allow you to focus your debugging efforts in the correct area. Use PerfMon to examine the following performance counters for the application: Process/Private Bytes, .NET CLR Memory/# Bytes in All Heaps, and .NET CLR LocksAndThreads/# of current logical Threads. The Process/Private Bytes counter reports all memory that is exclusively allocated for a process and can't be shared with other processes on the system. The .NET CLR Memory/# Bytes in All Heaps counter reports the combined total size of the Gen0, Gen1, Gen2, and large object heaps. The .NET CLR LocksAndThreads/# of current logical Threads counter reports the number of logical threads in an AppDomain. If an application's logical thread count is increasing unexpectedly, thread stacks are leaking. If Private Bytes is increasing, but # Bytes in All Heaps remains stable, unmanaged memory is leaking. If both counters are increasing, memory in the managed heaps is building up.

     

     


    Please mark the response as answers if it solves your question or vote as helpful if you find it helpful. My Blog: http://ashishkhandelwal.arkutil.com
    • Proposed as answer by Ashish Khandelwal Thursday, July 15, 2010 7:06 AM
    • Marked as answer by kicaj Thursday, July 15, 2010 8:30 AM
    Thursday, July 15, 2010 7:06 AM
  • What is the difference between counter „Page File Bytes” and “Virtual Bytes”?


    I have read explanations:


    “Page File Bytes is the current number of bytes that this process has used in the paging file(s). Paging files are used to store pages of memory used by the process that are not contained in other files. Paging files are shared by all processes, and the lack of space in paging files can prevent other processes from allocating memory.”


    “Virtual Bytes is the current size, in bytes, of the virtual address space the process is using. Use of virtual address space does not necessarily imply corresponding use of either disk or main memory pages. Virtual space is finite, and the process can limit its ability to load libraries.”


    So I thought that Page File Bytes are bytes that are stored on file on disk and Virtual Bytes are sum of RAM and bytes from disk but it looks that it is not true.


    I have three counters: Page File Bytes, Virtual Bytes, Private Bytes.


    After creation collection from my example I see that Page File Bytes are equal to Private Bytes (about 600 MB). Does it mean that all application is stored on page file on disk?
    And why Virtual Bytes show higher value than Page File Bytes and Private Bytes about 800 MB?


    Could you give me some better explanation?
    Regards

    Thursday, July 15, 2010 10:55 AM