Do you need to dispose of objects and set them to null?

前端 未结 11 1841
不思量自难忘°
不思量自难忘° 2020-11-22 10:58

Do you need to dispose of objects and set them to null, or will the garbage collector clean them up when they go out of scope?

相关标签:
11条回答
  • 2020-11-22 11:27

    If they implement the IDisposable interface then you should dispose them. The garbage collector will take care of the rest.

    EDIT: best is to use the using command when working with disposable items:

    using(var con = new SqlConnection("..")){ ...
    
    0 讨论(0)
  • 2020-11-22 11:29

    Always call dispose. It is not worth the risk. Big managed enterprise applications should be treated with respect. No assumptions can be made or else it will come back to bite you.

    Don't listen to leppie.

    A lot of objects don't actually implement IDisposable, so you don't have to worry about them. If they genuinely go out of scope they will be freed automatically. Also I have never come across the situation where I have had to set something to null.

    One thing that can happen is that a lot of objects can be held open. This can greatly increase the memory usage of your application. Sometimes it is hard to work out whether this is actually a memory leak, or whether your application is just doing a lot of stuff.

    Memory profile tools can help with things like that, but it can be tricky.

    In addition always unsubscribe from events that are not needed. Also be careful with WPF binding and controls. Not a usual situation, but I came across a situation where I had a WPF control that was being bound to an underlying object. The underlying object was large and took up a large amount of memory. The WPF control was being replaced with a new instance, and the old one was still hanging around for some reason. This caused a large memory leak.

    In hindsite the code was poorly written, but the point is that you want to make sure that things that are not used go out of scope. That one took a long time to find with a memory profiler as it is hard to know what stuff in memory is valid, and what shouldn't be there.

    0 讨论(0)
  • 2020-11-22 11:36

    You never need to set objects to null in C#. The compiler and runtime will take care of figuring out when they are no longer in scope.

    Yes, you should dispose of objects that implement IDisposable.

    0 讨论(0)
  • 2020-11-22 11:37

    If the object implements IDisposable, then yes, you should dispose it. The object could be hanging on to native resources (file handles, OS objects) that might not be freed immediately otherwise. This can lead to resource starvation, file-locking issues, and other subtle bugs that could otherwise be avoided.

    See also Implementing a Dispose Method on MSDN.

    0 讨论(0)
  • 2020-11-22 11:40

    Objects will be cleaned up when they are no longer being used and when the garbage collector sees fit. Sometimes, you may need to set an object to null in order to make it go out of scope (such as a static field whose value you no longer need), but overall there is usually no need to set to null.

    Regarding disposing objects, I agree with @Andre. If the object is IDisposable it is a good idea to dispose it when you no longer need it, especially if the object uses unmanaged resources. Not disposing unmanaged resources will lead to memory leaks.

    You can use the using statement to automatically dispose an object once your program leaves the scope of the using statement.

    using (MyIDisposableObject obj = new MyIDisposableObject())
    {
        // use the object here
    } // the object is disposed here
    

    Which is functionally equivalent to:

    MyIDisposableObject obj;
    try
    {
        obj = new MyIDisposableObject();
    }
    finally
    {
        if (obj != null)
        {
            ((IDisposable)obj).Dispose();
        }
    }
    
    0 讨论(0)
  • 2020-11-22 11:40

    I agree with the common answer here that yes you should dispose and no you generally shouldn't set the variable to null... but I wanted to point out that dispose is NOT primarily about memory management. Yes, it can help (and sometimes does) with memory management, but it's primary purpose is to give you deterministic releasing of scarce resources.

    For example, if you open a hardware port (serial for example), a TCP/IP socket, a file (in exclusive access mode) or even a database connection you have now prevented any other code from using those items until they are released. Dispose generally releases these items (along with GDI and other "os" handles etc. which there are 1000's of available, but are still limited overall). If you don't call dipose on the owner object and explicitly release these resources, then try to open the same resource again in the future (or another program does) that open attempt will fail because your undisposed, uncollected object still has the item open. Of course, when the GC collects the item (if the Dispose pattern has been implemented correctly) the resource will get released... but you don't know when that will be, so you don't know when it's safe to re-open that resource. This is the primary issue Dispose works around. Of course, releasing these handles often releases memory too, and never releasing them may never release that memory... hence all the talk about memory leaks, or delays in memory clean up.

    I have seen real world examples of this causing problems. For instance, I have seen ASP.Net web applications that eventually fail to connect to the database (albeit for short periods of time, or until the web server process is restarted) because the sql server 'connection pool is full'... i.e, so many connections have been created and not explicitly released in so short a period of time that no new connections can be created and many of the connections in the pool, although not active, are still referenced by undiposed and uncollected objects and so can't be reused. Correctly disposing the database connections where necessary ensures this problem doesn't happen (at least not unless you have very high concurrent access).

    0 讨论(0)
提交回复
热议问题