Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7748497
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 1, 20262026-06-01T10:48:01+00:00 2026-06-01T10:48:01+00:00

I made a 64-bit WPF test app. With my app running and with Task

  • 0

I made a 64-bit WPF test app. With my app running and with Task Manager open, I watch my system memory usage. I see I’m using 2GB, and I have 6GB available.

In my app, I click an Add button to add a new 1GB byte array to a list. I see my system memory usage increases by 1GB. I click Add a total of 6 times, filling the 6GB of memory I had available when I started.

I click a Remove button 6 times to remove each array from the list. The removed byte arrays should not be referenced by any other object in my control.

When I Remove, I don’t see my memory go down.
But that’s OK with me, because I understand that GC is non-deterministic and all that.
I figure the GC WILL collect as needed.

So now with memory looking full, but expecting the GC to collect when needed, I Add again.
My PC starts slipping in and out of a disk thrashing coma.
Why didn’t the GC collect?
If that wasn’t the time to do it, when is?

As a sanity check, I have a button to force GC. When I push that, I quickly get 6GB back. Doesn’t that prove my 6 arrays were not being referenced and COULD have been collected had the GC knew/wanted to?

I’ve read a lot that says I shouldn’t call GC.Collect() but if GC doesn’t collect in this situation, what else can I do?

    private ObservableCollection<byte[]> memoryChunks = new ObservableCollection<byte[]>();
    public ObservableCollection<byte[]> MemoryChunks
    {
        get { return this.memoryChunks; }
    }

    private void AddButton_Click(object sender, RoutedEventArgs e)
    {
        // Create a 1 gig chunk of memory and add it to the collection.
        // It should not be garbage collected as long as it's in the collection.

        try
        {
            byte[] chunk = new byte[1024*1024*1024];
            
            // Looks like I need to populate memory otherwise it doesn't show up in task manager
            for (int i = 0; i < chunk.Length; i++)
            {
                chunk[i] = 100;
            }

            this.memoryChunks.Add(chunk);                
        }
        catch (Exception ex)
        {
            MessageBox.Show(string.Format("Could not create another chunk: {0}{1}", Environment.NewLine, ex.ToString()));
        }
    }

    private void RemoveButton_Click(object sender, RoutedEventArgs e)
    {
        // By removing the chunk from the collection, 
        // I expect no object has a reference to it, 
        // so it should be garbage collectable.

        if (memoryChunks.Count > 0)
        {
            memoryChunks.RemoveAt(0);
        }
    }

    private void GCButton_Click(object sender, RoutedEventArgs e)
    {
        GC.Collect();
        GC.WaitForPendingFinalizers();
    }
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-01T10:48:02+00:00Added an answer on June 1, 2026 at 10:48 am

    As a sanity check, I have a button to force GC. When I push that, I quickly get 6GB back. Doesn’t that prove my 6 arrays were not being referenced and COULD have been collected had the GC knew/wanted to?

    You are probably better off asking When does the GC automatically collect "garbage" memory?. Off the top of my head:

    • Most commonly, when generation 0 is full or an object allocation won’t fit in the available free space.1
    • Somewhat commonly, when allocating a chunk of memory would cause an OutOfMemoryException, a full GC is triggered to first try and reclaim available memory. If not enough contiguous memory is available after the collection, then an OOM exception will be thrown.

    When starting a garbage collection, the GC determines what generations need to be collected (0, 0+1, or all). Each generation has a size determined by the GC (it can change as the application runs). If only generation 0 will exceed its budget, that is the only generation whose garbage will be collected. If the objects that survive generation 0 will cause generation 1 to go over its budget, then generation 1 will also be collected and its surviving objects will be promoted to generation 2 (which is the highest generation in Microsoft’s implementation). If the budget for generation 2 is exceeded as well, garbage will be collected, but objects can’t be promoted to a higher generation, as one doesn’t exist.

    So, here lies the important information, in the most common way the GC is started, Generation 2 will only be collected if generation 0 and generation 1 are both full. Also, you need to know that objects over 85,000 bytes are not stored in the normal GC heap with generation 0, 1, and 2. It’s actually stored in what is called the Large Object Heap (LOH). The memory in the LOH is only freed during a FULL collection (that is, when generation 2 is collected); never when only generations 0 or 1 are being collected.

    Why didn’t the GC collect? If that wasn’t the time to do it, when is?

    It should now be obvious why the GC never happened automatically. You’re only creating objects on the LOH (keep in mind that int types, the way you’ve used them, are allocated on the stack and don’t have to be collected). You are never filling up generation 0, so a GC never happens.1

    You’re also running it in 64-bit mode, which means it’s unlikely you’ll hit the other case I listed above, where a collection occurs when there’s not enough memory in the entire application to allocate a certain object. 64-bit applications have a virtual address space limit of 8TB so it would be a while before you hit this case. It’s more likely you’ll run out of physical memory and page file space before that happens.

    Since a GC hasn’t happened, windows starts to allocate memory for your application from the available space in the page file.

    I’ve read a lot that says I shouldn’t call GC.Collect() but if GC doesn’t collect in this situation, what else can I do?

    Call GC.Collect() if this kind of code is what you need to write. Better yet, don’t write this kind of code outside of testing.

    In conclusion, I have not done justice to the topic of automatic garbage collection in the CLR. I recommend reading about it (it’s actually very interesting) via msdn blog posts, or as has already been mentioned, Jeffery Richter’s excellent book, CLR Via C#, Chapter 21.


    1 I’m making the assumption that you understand that the .NET implementation of the GC is a generational garbage collector. In the simplest terms, it means that newly created objects are in a lower numbered generation, i.e. generation 0. As garbage collections are run and it’s found that an object that is in a certain generation has a GC root (not “garbage”), it will be promoted to the next generation up. This is a performance improvement since GC can take a long time and hurt performance. The idea is that objects in higher generations generally have a longer life and will be around in the application longer, so it doesn’t need to check that generation for garbage as much as the lower generations. You can read more in this wikipedia article. You’ll notice it’s also called a ephemeral GC.

    2 If you don’t believe me, after you remove one of the chunks, have a function that creates a whole bunch of random strings or objects (I’d recommend against arrays of primitives for this test) and you’ll see after you reach a certain amount of space, a full GC will occur, freeing that memory you had allocated in the LOH.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

After taking some small courses and using WPF and C# a bit I've decided
I ran different tests recently on a .net app to see how memory footprint
I am using a library developed in C (particularly: HTK). I've made a bit
Resharper (paired with StyleCop) has made me a bit of a neat freak when
I am trying to teach myself a bit of Javascript and made this collection
I have been playing around a bit with a fairly simple, home-made search engine,
Ok, the title is a bit confusing, but here's my predicament. I've made a
I made the ultimate laugh generator using these rules. Can you implement it in
In a previous question , I made a bit of a faux pas. You
In an answer to another question I made a simple bit of code to

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.