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 8708511
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 13, 20262026-06-13T04:09:28+00:00 2026-06-13T04:09:28+00:00

I’ve encountered an issue with finalizable objects that doesn’t get collected by GC if

  • 0

I’ve encountered an issue with finalizable objects that doesn’t get collected by GC if Dispose() wasn’t called explicitly.
I know that I should call Dispose() explicitly if an object implements IDisposable, but I always thought that it is safe to rely upon framework and when an object becomes unreferenced it can be collected.

But after some experiments with windbg/sos/sosex I’ve found that if GC.SuppressFinalize() wasn’t called for finalizable object it doesn’t get collected, even if it becomes unrooted. So, if you extensively use finalizable objects(DbConnection, FileStream, etc) and not disposing them explicitly you can encounter too high memory consumption or even OutOfMemoryException.

Here is a sample application:

public class MemoryTest
{
    private HundredMegabyte hundred;

    public void Run()
    {
        Console.WriteLine("ready to attach");
        for (var i = 0; i < 100; i++)
        {
            Console.WriteLine("iteration #{0}", i + 1);
            hundred = new HundredMegabyte();
            Console.WriteLine("{0} object was initialized", hundred);
            Console.ReadKey();
            //hundred.Dispose();
            hundred = null;
        }
    }

    static void Main()
    {
        var test = new MemoryTest();
        test.Run();
    }
}

public class HundredMegabyte : IDisposable
{
    private readonly Megabyte[] megabytes = new Megabyte[100];

    public HundredMegabyte()
    {
        for (var i = 0; i < megabytes.Length; i++)
        {
            megabytes[i] = new Megabyte();
        }
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    ~HundredMegabyte()
    {
        Dispose(false);
    }

    private void Dispose(bool disposing)
    {
    }

    public override string ToString()
    {
        return String.Format("{0}MB", megabytes.Length);
    }
}

public class Megabyte
{
    private readonly Kilobyte[] kilobytes = new Kilobyte[1024];

    public Megabyte()
    {
        for (var i = 0; i < kilobytes.Length; i++)
        {
            kilobytes[i] = new Kilobyte();
        }
    }
}

public class Kilobyte
{
    private byte[] bytes = new byte[1024];
}

Even after 10 iterations you can find that memory consumption is too high(from 700MB to 1GB) and gets even higher with more iterations. After attaching to process with WinDBG you can find that all large objects are unrooted, but not collected.

Situation changes if you call SuppressFinalize() explicitly: memory consumption is stable around 300-400MB even under high pressure and WinDBG shows that there are no unrooted objects, memory is free.

So the question is: Is it a bug in framework? Is there any logical explanation?

More details:

After each iteration, windbg shows that:

  • finalization queue is empty
  • freachable queue is empty
  • generation 2 contains objects(Hundred) from previous iterations
  • objects from previous iterations are unrooted
  • 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-13T04:09:29+00:00Added an answer on June 13, 2026 at 4:09 am

    An object with a finalizer doesn’t behave the same way as an object lacking one.

    When a GC occurs, and SuppressFinalize has not been called, the GC won’t be able to collect the instance, because it must execute the Finalizer. Therefore, the finalizer is executed, AND the object instance is promoted to generation 1 (object which survived a first GC), even if it’s already without any living reference.

    Generation 1 (and Gen2) objects are considered long lived, and will be considered for garbage collection only if a Gen1 GC isn’t sufficient to free enough memory. I think that during your test, Gen1 GC is always sufficient.

    This behavior has an impact on GC performance, as it negates the optimisation brought by having several générations (you have short duration objects in the gen1 ).

    Essentially, having a Finalizer and failing to prevent the GC from calling it will always promote already dead objects to the long lived heap, which isn’t a good thing.

    You should therefore Dispose properly your IDisposable objects AND avoid Finalizers if not necessary (and if necessary, implement IDisposable and call GC.SuppressFinalize. )

    Edit:
    I didn’t read the code example well enough: Your data looks like it is meant to reside in the Large Object Heap (LOH), but in fact isn’t: You have a lot of small arrays of references containing at the end of the tree small arrays of bytes.

    Putting short duration object in the LOH is even worse, as they won’t be compacted… And therefore you could run OutOfMemory with lot of free memory, if the CLR isn’t able to find an empty memory segment long enough to contains a large chunk of data.

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

Sidebar

Related Questions

I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
I know there's a lot of other questions out there that deal with this
link Im having trouble converting the html entites into html characters, (&# 8217;) i
That's pretty much it. I'm using Nokogiri to scrape a web page what has
I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
I've got a string that has curly quotes in it. I'd like to replace
I have a small JavaScript validation script that validates inputs based on Regex. I
I have a French site that I want to parse, but am running into
I am doing a simple coin flipping experiment for class that involves flipping a
Does anyone know how can I replace this 2 symbol below from the string

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.