Lowdown on finalization

  • Thread starter Thread starter Frank Rizzo
  • Start date Start date
F

Frank Rizzo

Can someone give a reader's digest on finalization of objects in .net
framework.

When do I need to call .Dispose?
What happens when I set the object to Nothing (or null in c#)
What else do I need to know?

Thanks
 
Can someone give a reader's digest on finalization of objects in .net
framework.

When do I need to call .Dispose?

When your object manages unmanaged resources (ex: Database connections,
sockets, file handles, os handles, etc). In these cases you'll want
your class to implement the IDisposable interface...

And of course, you'll want to call it on any class that implements it :)
What happens when I set the object to Nothing (or null in c#)

Not much really... It simply releases the reference, and if there are
no other references makes the object eligibale for gc. In the case of
local objects, it should usually be avoided...
What else do I need to know?

http://msdn.microsoft.com/library/d...guide/html/cpconimplementingdisposemethod.asp
 
Tom said:
When your object manages unmanaged resources (ex: Database connections,
sockets, file handles, os handles, etc). In these cases you'll want
your class to implement the IDisposable interface...

So implementing this interface means what? That when the client calls
..Dispose method on my object, I'll release whatever needs to be released?

How is that different from writing a ReleaseResources method where I
release all the resources?
And of course, you'll want to call it on any class that implements it :)

So should I set local objects to Nothing or not? What about class level
variables that I no longer need?

Also, how is Finalize different?
Not much really... It simply releases the reference, and if there are
no other references makes the object eligibale for gc. In the case of
local objects, it should usually be avoided...




http://msdn.microsoft.com/library/d...guide/html/cpconimplementingdisposemethod.asp

Thanks, this is good stuff. However, is it me or they made it a lot
more complicated than it needs to be? You pass true or false into
Dispose based on the identity of the caller??????? What? Was someone
smoking at ms? I am starting to miss the lack of backspace in vi.
 
So implementing this interface means what? That when the client calls
.Dispose method on my object, I'll release whatever needs to be released?

Yep.

How is that different from writing a ReleaseResources method where I
release all the resources?

There is no difference. IDisposable is just a formalized interface to
accomplish this. Basically, it is a convention.
So should I set local objects to Nothing or not? What about class level
variables that I no longer need?

Local objects don't need to be set to nothing because once the object is
out of scope and no longer referenced it is eligable for GC. In fact,
the JIT can actually optimize the code so that an local object is available
for GC even before the end of the method... Say you have this scenario:

Private Sub MySub()
Dim o As New MyObjectType

o.DoCoolStuff()

' Do a lot of stuff that doesn't have anything to do with o
End Sub

Because the method no longer referes to o, the JIT will make it
available for GC as soon as the call to DoCoolStuff is complete... It
seems in the Beta days setting the object to nothing could actually
interfere with this optimization - but I have since read that the JIT
will actually optimize away the assignment to nothing now.

For class level objects, it would probably be a good idea when they are
no longer needed.
Also, how is Finalize different?

Finalize is a method of object. It's purpose is essentially the same as
Dispose - release resources. The difference is that Finalize is called
by the GC, and should be avoided because it can have a negative impact
on the performance of the GC, because it actually takes two passes to
clean up an object that has overridden Finalize.

What you will usually see is that objects that contain unmanaged
resources will usually implement both IDisposable AND override finalize.
The Dispose implementation, will usually call GC.SuppressFinalize to
remove the object from the finalization queue. This way, you can make
sure that your resources will be released eventually - even if the
client forgets to call dispose. But if they do remember, then you don't
incure the performance hit.

One thing I've taken to doing lately, is actually throw an exception
from the finalize method (or you could use an assertion). This sort of
clues me in to when I haven't managed my resources properly :)
Thanks, this is good stuff. However, is it me or they made it a lot
more complicated than it needs to be? You pass true or false into
Dispose based on the identity of the caller??????? What? Was someone
smoking at ms? I am starting to miss the lack of backspace in vi.

Just covering the bases. For the most part, resource management is
pretty nice in .NET because the runtime can do most of the work for
you... Unfortunately, ever system has it's drawbacks, and there are
times when you have to take a more active role in the process :)
 
Tom said:
There is no difference. IDisposable is just a formalized interface to
accomplish this. Basically, it is a convention.

Ah, I got it.
Local objects don't need to be set to nothing because once the object is
out of scope and no longer referenced it is eligable for GC. In fact,


Ok, let's take 2 concrete examples with an object holding an actual
resource.

private sub MySub()
dim o as Sqlconnection = new SqlConnection("server=x;userid=sa")
o.Open

'do stuff
o.Execute ("drop master")
end sub

Am I right in thinking that GC may not immediately kill the o
(SqlConnection) object, leaving the connection to the database open for
undetermined amount of time?

Assuming I am correct, I'd need to do the following:

....
o.Close
o.Dispose
end Sub

Correct?


Second example, this time in pseudo-code

private sub MySub2()
dim oFile as File = new File("c:\autoexec.bat")
oFile.Open modeExclusiveWrite

oFile.Append ("some extra text")

oFile = Nothing
end sub

In this case, if someone else tried open c:\autoexec.bat, they would
fail because the file is opened for exclusive write and setting oFile to
Nothing has no immediate effect.

In other words, the proper way to do it would be manually call the
Dispose method on the oFile object (i am assuming such a method exists).

Am I right in my assumptions?
Finalize is a method of object. It's purpose is essentially the same as
Dispose - release resources. The difference is that Finalize is called
by the GC, and should be avoided because it can have a negative impact
on the performance of the GC, because it actually takes two passes to
clean up an object that has overridden Finalize.

What you will usually see is that objects that contain unmanaged
resources will usually implement both IDisposable AND override finalize.
The Dispose implementation, will usually call GC.SuppressFinalize to
remove the object from the finalization queue. This way, you can make
sure that your resources will be released eventually - even if the
client forgets to call dispose. But if they do remember, then you don't
incure the performance hit.

One thing I've taken to doing lately, is actually throw an exception
from the finalize method (or you could use an assertion). This sort of
clues me in to when I haven't managed my resources properly :)

Ok, so I am confused again. What should be I cleaning up in Finalize,
if all my resources were released in Dispose?
 
Ah, I got it.



Ok, let's take 2 concrete examples with an object holding an actual
resource.

private sub MySub()
dim o as Sqlconnection = new SqlConnection("server=x;userid=sa")
o.Open

'do stuff
o.Execute ("drop master")
end sub

Am I right in thinking that GC may not immediately kill the o
(SqlConnection) object, leaving the connection to the database open for
undetermined amount of time?


Assuming I am correct, I'd need to do the following:

...
o.Close
o.Dispose
end Sub

Correct?

Correct, except in this case the Dispose is redundant... o.Close
basically does the same thing - release the connection :)
Second example, this time in pseudo-code

private sub MySub2()
dim oFile as File = new File("c:\autoexec.bat")
oFile.Open modeExclusiveWrite

oFile.Append ("some extra text")

oFile = Nothing
end sub

In this case, if someone else tried open c:\autoexec.bat, they would
fail because the file is opened for exclusive write and setting oFile to
Nothing has no immediate effect.

Exactly

In other words, the proper way to do it would be manually call the
Dispose method on the oFile object (i am assuming such a method exists).

Dispose or Close.
Am I right in my assumptions?

Pretty much. GC is indeterminate
Ok, so I am confused again. What should be I cleaning up in Finalize,
if all my resources were released in Dispose?

The same resources you cleaned up in Dispose... Think of it as a back
stop. If the client forgets to call Dispose, then you know that your
resources will get cleaned up - eventually.

Jay, gave some pretty good links on the subject - they may be able to
explain it a little clearer...
 
Back
Top