Getting Started with Adobe After Effects - Part 6: Motion Blur
First Time? You can support us by signing up. It takes only 5 seconds. Click here to sign up. If you already have an account, click here to login.
Loading

1st Prize - Apple iPad


DOTNET Quiz 2011 - What happens when you do NOT dispose an object in .NET?

  • Objects that consume resources like file handles, image handles, database connections, etc, have a Dispose method to free the resource when it is no longer needed. If you do not call the Dispose method what happens?

    Posted on 01-31-2011 00:00 |
    Steve Wellens
    764 · 0% · 41

12  Answers  

Subscribe to Notifications
Previous 1 | 2 Next
  • Score
    5

    Objects that are not disposed off by the developer stay in memory until the Garbage Collector (GC) comes around and disposes them.
    The GC then calls the Dispose method of the object before freeing the memory used by it.

    The GC, howver, is a background task that is called by the .net framework whenever it decides that there is need for it. So the object can live for as long as the application lives, or could be disposed right the next processor tick. This uncertainty is useful for programs that use "hot spots" of object activation/deletion where the displosal would have a negative impacot on the execution time of the hot spot. Here the GC can suspend disposing objects until a later phase when the application is less active.
    For the object types mentioned here this can be dangerous to the application as the handles and connections held by the object will typically remain open untio the Dispose() method is called. Some objects (like connection objects) have a Close() method that frees the handles, but others don't.

    Best practice tells that you should call the Dispose method of objects in your code if the object holds limited resources, and that you should leave objects that do not hold limited resources to the GC.

    Another problem with the GC is that it runs on it's own thread, so the dispose call could happen on another thread than the object activation, so the program code has to take this into account.

    Replied on Jan 31 2011 1:04AM  . 
    Guenter
    28 · 6% · 1887
  • Score
    5

    The pattern is to define a finalizer that cleans stuff up in case dispose is not called and then have dispose suppress the finalizer. Which reduces memory load and gives the GC less work to do.

    Amongst the many problems with calling Dispose from the finalizer, is that you are turning a single threaded problem into a multithreaded problem, the finalizer will run on a different thread which can expose some very subtle and hard to catch bugs. Also, it means you will be holding on to unmanaged resources for longer than expected.

    it is a best practice to dispose all disposable objects, otherwise you can introduce weird and complex bugs

    Replied on Jan 31 2011 2:50AM  . 
    shah184
    1591 · 0% · 12
  • Score
    7

    When you don’t call the Dispose method explicitly, the GC (Garbage Collector) does it for you. Even after you call the Dispose method, the object is not immediately disposed from memory. It is just handed over to the GC. The object is handed over to GC either when Dispose method is called, or as soon as the last reference to the object goes out of scope. The GC can then decide when to actually dispose off the object from memory and act accordingly depending on the free memory available and how busy is the program. It usually will dispose the object when the program is idle or the memory usage has exceeded half the total memory available to the program.

    Ideally you should never need to call the Dispose method explicitly, though it is a good practice to call it explicitly for shared resources etc. Usually if a class is well written, it will provide methods to free resources like Close the connection, Close the file, Close the memory stream etc. So calling that method is sufficient. With objects that don't use shared resources, it is hardly ever a good decision to call the Dispose method explicitly.

    More often than not, explicitly calling Dispose will degrade the performance of your program. I prefer never to call the dispose method explicitly, unless absolutely necessary. Besides keeping my code short and clean, you also get the advantages of the GC intelligence. It is best to leave it to the GC unless you have a good reason to explicitly Dispose the object yourself. The GC has a good logic to judge & decide when to remove object from memory while having the least impact on the performance of the program.

    Replied on Jan 31 2011 3:04AM  . 
    Pradeep Kumar
    300 · 0% · 145
  • Score
    10

    I thought I'd better jump in and answer my own question and clear up some misconceptions:

    Close and Dispose are not the same. If you Close a database connection, you can reopen it later. If you Dispose a database connection you cannot use it anymore. You must create a new database object.

    In a properly constructed object, if it has a Dispose method you should always call it as soon as possible when finished with it. You can also use the Using statement:

        using (SqlConnection Conn = new SqlConnection(MyConnectionString))
        {
            // code here
        }
    

    To answer the original question: You run the risk of running out of resources.

    If you make too many database connections without disposing them you will get this exception:

    An exception of type 'System.InvalidOperationException' occurred in System.Data.dll but was not handled in user code Additional information: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.

    Replied on Jan 31 2011 6:26PM  . 
    Steve Wellens
    764 · 0% · 41
  • Score
    7

    My answer was in context of object going out of scope or the last reference to the object is lost, so that the GC can take charge of it. If your object is still in scope and can be used/referenced then GC won't do anything on it. The Dispose is ultimately called anyways - either you call it or the GC does it. The question is - when?

    It is obvious that Close and Dispose are two different things and serve completely two different purposes.

    I agree that using the Using construct is still the better option.

    Replied on Feb 1 2011 1:48AM  . 
    Pradeep Kumar
    300 · 0% · 145
  • Score
    9

    Dispose of an object the instant your are done with it. Disposable objects represent objects holding a valuable resource which the CLR is not intrinsically aware of. Consequently the GC is also unaware of the resources and is unable to make intelligent decisions as to when it should collect a disposable object and hence free the underlying resource.

    Eventually the GC will feel memory pressure and collect your object by coincidence (nothing more). If you don't dispose of objects in a deterministic manner then it is completely possible to enter a resource starved state with almost no memory pressure.

    Quick example of how this can happen. Lets think of the underlying resource as Win32 handle. These are very finite and fairly small. You run an operation that create a lot of objects.objects implement IDisposable and are responsible for creating and disposing of a Win32 handle. They are not manually freed and by a difference quirk make it into the Gen2 heap. This heap is freed fairly infrequently. Over time enough object instances make it into the Gen2 heap to take up all of the available handles. New objects are consequently unable to be created regardless of how much memory is being used.

    In fact to free the handles, it would take a rather large amount of memory to be allocated during a single operation to give enough pressure to free the instances.

    Replied on Feb 11 2011 8:50AM  . 
    merwan
    507 · 0% · 74
  • Score
    9

    If we are not calling dispose method there is a risk of running out of resources . Its best practice to call dispose method as soon as we finish using any objects like images, files ,database connections.

    another way of dsiposing is by using using statement. The using statement simplifies the code that you have to write to create and then finally clean up the object. The using statement obtains the resource specified, executes the statements and finally calls the Dispose method of the object to clean up the object. The following piece of code illustrates its use.

     using (TextWriter w = File.CreateText("log.txt"))
        {
            w.WriteLine("This is line one");
        }
    

    The using statement is only useful for objects with a lifetime that does not extend beyond the method in which the objects are constructed. Remember that the objects you instantiate must implement the System.IDisposable interface.

    There is no equivalent for the using statement in vb.net.

    Replied on Feb 14 2011 4:40AM  . 
    Vamshi
    133 · 1% · 376
  • Score
    7

    @Vamshi: VB.NET does have a Using statement and works same as the C# equivalent.

    Here is the VB.NET equivalent of your code:

    Using w As TextWriter = File.CreateText("log.txt")
        w.WriteLine("This is line one")
    End Using
    Replied on Feb 14 2011 4:53AM  . 
    Pradeep Kumar
    300 · 0% · 145
  • Score
    9

    Handles are data structures that represent open instances of basic operating system objects applications interact with. Handles are limited resource, so the number of handles a process can create is limited. There are two limits related to the number of handles: the maximum number of handles the system sets for a process and the amount of memory available to store the handles and the objects the application is referencing with its handles. In general an application that creates more than 10,000 handles is considered to be either poorly designed or having a handle leak, however actual limits on handles are far beyond that number. An application that fails to release unneeded resources causes a leak of the resource and could be resulting in bizarre and difficult to diagnose behaviors for the application, other applications or the system in general. As an example after I tried to execute a code like this:

    ArrayList al = new ArrayList(); 
    
    for (int i = 1; i < 300000; i++) 
    { 
    al.Add(File.OpenRead("C:\\Sample.txt")); 
    }
    

    I had to reboot my computer as it started to behave a bit strange. Besides the last 100,000 of handles were creating about 10 times slower than the first 100,000. A nice article describing internals of handles and how they work can be found here Pushing the Limits of Windows: Handles .

    The situation with database connections is a bit different. Besides system handles, they are also limited by a size of connection pool. An application cannot open more connections to a database than allowed by connection pool maximum size. Thus if connection is not closed or disposed you'll get an error when you reach connection pool limit. As an example if you execute:

    ArrayList al = new ArrayList(); 
    SqlConnection sc = null; 
    
    for (int i = 1;; i++) 
    { 
    sc = new SqlConnection([Connection String]); 
    sc.Open(); 
    al.Add(sc); 
    }
    

    You'll get an error "Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached."

    You can also use Close() method to close a connection. However there is an interesting thing about it. MSDN states "...you must explicitly close the connection by calling Close or Dispose. Close and Dispose are functionally equivalent." I found it not 100% true though. Both close a connection. However Dispose method does some more "cleaning” e.g. cleans a connection string. But... it looks like that you still can open a connection after you called Dispose method on it. I am not sure this is a good practice though. The only thing you have to do is to set connection string. As an example the code listed below worked just fine for me:

    SqlConnection sc = new SqlConnection([Connection string]); 
    sc.Open(); 
    sc.Close(); 
    sc.Open(); 
    sc.Dispose(); 
    sc.ConnectionString = [Connection string]; 
    sc.Open(); 
    sc.Close();
    

    And definitely applying using statement is a excellent option to make sure the object will be disposed.

    All in all, if we keep creating handles, but do not release them (for example by using Dispose method) we are at risk to run out of this resource.

    Replied on Mar 31 2011 9:06PM  . 
    Dmitry Kharlap (aka Docker)
    150 · 1% · 325
  • Score

    This question is already closed and Steve and others have already answered it but it should be noted that the GC does not call the Dispose method at all

    Replied on Jul 2 2011 1:52AM  . 
    bptolemy
    1890 · 0% · 10
Previous 1 | 2 Next

Your Answer


Sign Up or Login to post an answer.
Please note that your answer will not be considered as part of the contest because the competition is over. You can still post an answer to share your knowledge with the community.

Copyright © Rivera Informatic Private Ltd.