Memory release with IDisposable and without IDisposable

雨燕双飞 提交于 2019-12-22 10:42:41

问题


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.


回答1:


As @Steven pointed out in his comments, IDisposable is something the CLR doesn't care about. By implementing it you simply tell consumers of your object to call its Dispose method when object no longer needed. In terms of mem management you can make up your own interface for this, say IDisposable2, and get the same technical effect. This would however be a stupid thing to do because .net developers should know to call idisposable.dispose when object no longer needed. Also, there is built in language (c#) support for this interface (using {...}).

You write "I tried to implement IDisposable and then the ram goes down immideitly."

What matters is what your "implement" does. The code there should clean up unmanaged code, windows resources etc.




回答2:


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.




回答3:


Using IDisposable means that you are implementing Dispose method where you put all your clean up code for the resources that you dont need anymore. It does not remove your object to the managed heap, the GC will still be the one responsible for freeing up the memory.




回答4:


When you implement IDisposable, and dispose the object, you are marking the object as available to be garbage-collected.

You can't predict exactly when it will be collected though.



来源:https://stackoverflow.com/questions/11359131/memory-release-with-idisposable-and-without-idisposable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!