Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory release with IDisposable and without IDisposable

In my app I have a large object that's created every few seconds. I do with it some job and then I don't need it anymore.

I saw in the task manager that the ram size goes up even if I don't have any reference to the object and it needs to be collected.

After implementing IDisposable the ram goes down immediately.

Why is this? I didn't do GC.Collect, I just released the object and told the GC it doesn't need to call the finalizer for my object.

EDIT:

Here is the code I use for my IDisposable objects:

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

private void Dispose(bool disposing)
{
  //here i release unmanaged resources
  if (disposing)
  {
    //here i release all managed resources
  }
}

~MyObject()
{
  Dispose(false);
}

In my large object, I do myObject.Dispose(); after I don't need it anymore.

My question was not about how to implement IDisposable or how GC works in general. I just want to know how is it possible that there's a difference when I dispose of the object myself or let GC do its job.

like image 955
user1226847 Avatar asked Dec 27 '25 23:12

user1226847


1 Answers

With .NET memory doesn't have 2 states as usual (used and unused), but in effect 4: (A) Used by live object, (B) Used by dead object, (C) Not used by any object, but by the framework and (D) not used.

When you create an object, the Framework will first try to use memory of category (C) for it, is there isn't enough usable left of it, it will ask the OS for some of type (D), will convert it into (C) and then use it for your object.

When an object goes out of scope, it will fall from (A) to (B), on the next garbage run it will go from (B) to either (C) or (D). This depends heavily on the internal structures (think memeory fragmentation and friends), of the memory pressure and of the type of object collected (think IDisposable and friends)

What you want to achieve is, that as fast as possible after your big Object goes out of scope, the memory it used goes to (D). Here are some hints:

  • Make sure your object's size is a multiple of 4K - this makes it much more likely, that no other object shares a memory page with your object, so it can more easily be given back to the OS

  • Experiment with a AddMemoryPressure() bracket around object disposal, but be aware of side effects. This is similar to forcing GC.Collect(), but less intrusive: It will hint the GC to collect soon, but not exactly now

  • Rethink your basic concept: Is the big object a Singleton (i.e. only one can exist at any given time)? If yes, think of allocating it once and recycling it: This will make your Applications RAM requirements more predictable - and possible save you from ugly OOM situations while running.

like image 109
Eugen Rieck Avatar answered Dec 30 '25 13:12

Eugen Rieck



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!