2

So does implementing Dispose() on the managed objects where would improve Garbage Collector's performance by getting a hint from the to probably bypass some of its whole process.

I saw this answer on a question which didn't get high vote but is this true? If yes then how?

No that is wrong. I agree with Aaronaught. In addition, Microsoft recommends, in a mid 2003 webcast that Don Box presented, that every .Net developer should dispose of their own objects, whether managed or unmanaged, as this improves code performance by anything upto 20%. If done right it can be a substantial performance improvement. So its a core skill that every .net developer needs to know and use.

Community
  • 1
  • 1
luqi
  • 2,779
  • 2
  • 18
  • 14

4 Answers4

6

You simply can't Dispose of managed memory in the same way that you can call Dispose to release file handles etc. The only thing which can clean up managed memory is the garbage collector.

You could make a Dispose method set all the variables in a class to null in the hope that this would allow the garbage collector to collect all the previously-referred-to objects earlier - but there are very few situations where it would actually help, as typically your object will become eligible for collection at the same time anyway. It would also make your code much harder to follow.

The ability to not have to worry about an object's lifetime in most cases is one of C#'s benefits - why would you want to get rid of that by making every class implement IDisposable? Do you really want to manage "ownership" and lifetime yourself?

I suspect you've misread the (admittedly somewhat unclear) answer that you quoted in your question. I don't believe it's advocating the disposal of all objects - I believe it's advocating being explicit about disposing of instances of types which already implement IDisposable. This has nothing to do with purely-managed types, which almost never implement IDisposable.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Yes I meant calling Dispose method and set all variables/object references to null. I will edit my question to reflect that. Can you please elaborate on the few situations where it could help? – luqi Jul 08 '11 at 06:19
  • I agree that I won't use it on all classes. Just need to know if its useful, in which situations it would be. – luqi Jul 08 '11 at 06:21
  • @luqi: It's almost *never* useful, and it would be very hard for the *class designer* to predict the cases in which it would be useful. It makes it harder to use for *all* callers, as they have to worry about lifetime and ownership. Just don't do it. – Jon Skeet Jul 08 '11 at 06:22
3

First off, by calling Dispose methods, it in no way hints the GC that anything special should be done. Dispose is a normal method, like any other.

The magic sauce is what Dispose does, namely releasing resources that are no longer needed.

The #1 rule with IDisposable objects is to call Dispose when you're finished with them. Yes the GC may eventually clean out memory, but if the objects are still linked to any others that are still in use, they will remain. Dispose also cleans up unmanaged resources, which is crucial, such DB connections, file handles, locks, etc. These definitely need to be closed ASAP.

In short, if you instantiated an IDisposable object, Dispose of it when done.

Yes it has a cost to call Dispose, but as I stated earlier, it means objects can be unlinked from each other, allowing the GC to free them next time it runs. It also means unmanaged resources can be freed immediately. Another win. Memory and resource leaks can cost performance badly, as can application crashes if it gets too extreme!

The developer may have been protecting important resources, so please don't try to second-guess him!

Profiling is your friend here. If performance of re-creating these objects is a concern, cache them, but still be prepared to dispose of them when finished.

Will
  • 2,512
  • 14
  • 19
  • I am only interested in the performance improvement for the managed objects for this question. – luqi Jul 08 '11 at 06:24
3

As pointed out by Jon Skeet this code is bad code design:


 public class SomeClass : IDisposable
    {
        private string SomeData;

        public void LoadFileIntoMemory(string filename)
        {
            using (var sr = new StreamReader(filename))
            {
                SomeData = sr.ReadToEnd();
            }
        }
        public void DoSomethingWithDataInMemory()
        {
            //whatever
        }
        public void Dispose()
        {
            SomeData = null;
        }
    }

    class Program
    {
        public static void Main()
        {
            using (var sC = new SomeClass())
            {
                sC.LoadFileIntoMemory("somefile");
                sC.DoSomethingWithDataInMemory();
            }
        }
    }

It is much better to simply do this


 public class SomeClass
    {
        private string SomeData;

        public void LoadFileIntoMemory(string filename)
        {
            using (var sr = new StreamReader(filename))
            {
                SomeData = sr.ReadToEnd();
            }
        }
        public void DoSomethingWithDataInMemory()
        {
            //whatever
        }
    }

    class Program
    {
        public static void Main()
        {
            var sC = new SomeClass();
            sC.LoadFileIntoMemory("somefile");
            sC.DoSomethingWithDataInMemory();
            sC = null;
        }
    }

IDisposable should strictly be implemented when your class uses some resources which will not be cleared if a variable for an instance of a class is set to null :) . All managed resources will be cleared when you set the containing instance to null (when the gc runs).

basarat
  • 261,912
  • 58
  • 460
  • 511
0

Yes, I agree with that. Because garbage collector does its job to free memory with the components not in used, but it does on time to time, if developer by him self does this job, this will affect the performance in the way that extra object will not remain in memory, despite that it memory waits for the garbage collector to clean.

Ovais Khatri
  • 3,201
  • 16
  • 14