Garbage Collection

M

Michael Hart

I have a form that creates new objects in all sorts of fashion using vb.net.

Some are created when the form opens with

Private varName as new Object()

just near the form class

In some subs I have

Sub Internal1()
Dim myVar as new Object()
End Sub

in the declaration section

and also sometimes I have the constructer separate to the declaration

Sub Internal2()
Dim newVar as Object

newVar = new Object(parm1, parm2)
End Sub

Do I need to explicitly dispose of these objects or will the garbage
collector [if there is one] take care of it when they go out of scope?

When I do a Me.Close on a form does it invoke the garbage collector on the
form?
 
B

Bill McCarthy

Hi Michael,

If you can explicitly call Dispose, it is always best to do this as this
provides timely release of resources the object may be holding onto. If you
don't call Dispose, the GC will eventually collect them for you once they go out
of scope, but that may take some time, and system resources could get low if any
of the objects waiting to be collected are holding onto resources, such as
bitmaps, brushes, fonts, or just large objects that take up large amounts of
memory.
So, the general rule is if you can safely call IDisposable.Dispose on the
object, then do so.

HTH's

Bill.
 
M

Michael Hart

Thanks Bill,

2 further quesitons

1..
Do form object go out of scope when you call Me.Close on the form? If not
how do you make a form go out of scope?


2..
How does this work? I have some data access objects that I declare in the
declaration section of a sub then .Dispose of but they are still accessable.
Note in particular the DataAdapter, Dataset, Command and Parameter objects
in the following code. I would have thought that if I free the memory for
these objects with the .Dispose method it would throw some sort of bounds
exception if I tried to use them again. This code works without errors
everytime I use it. Why doesn't Dispose clear the objects?

Private Sub GetC()
Dim sqlStr As String
Dim C As Double
Dim con As New OleDb.OleDbConnection()
Dim cmd As New OleDb.OleDbCommand()
Dim da As New OleDb.OleDbDataAdapter()
Dim ds As New DataSet()
Dim parm As New OleDb.OleDbParameter()

C = 0
Try
sqlStr = "SELECT [C_Value], [ID] FROM
WHERE ([ID]= ? )"

con.ConnectionString = ADB_strCon
cmd.Connection = con
cmd.CommandText = sqlStr
parm.Direction = ParameterDirection.Input
parm.DbType = DbType.String
parm.ParameterName = "?"
parm.Value = txtProvider1.Text
parm.Size = Len(txtProvider1.Text)
cmd.Parameters.Add(parm)

da.SelectCommand = cmd
da.Fill(ds, "C_Value")
C = C + ds.Tables("C_Value").Rows(0)(0)

ds.Clear()
ds.Dispose()
da.Dispose()
cmd.Parameters.Clear()
cmd.Dispose()

cmd.Connection = con
cmd.CommandText = sqlStr
parm.Value = txtProvider2.Text
parm.Size = Len(txtProvider2.Text)
cmd.Parameters.Add(parm)

da.SelectCommand = cmd
da.Fill(ds, "C_Value")
C = C + ds.Tables("C_Value").Rows(0)(0)

ds.Clear()
ds.Dispose()
da.Dispose()
cmd.Parameters.Clear()
cmd.Dispose()

cmd.Connection = con
cmd.CommandText = sqlStr
parm.Value = txtProvider3.Text
parm.Size = Len(txtProvider3.Text)
cmd.Parameters.Add(parm)

da.SelectCommand = cmd
da.Fill(ds, "C_Value")
C = C + ds.Tables("C_Value").Rows(0)(0)

ds.Clear()
ds.Dispose()
da.Dispose()
cmd.Parameters.Clear()
cmd.Dispose()

Catch ex As Exception
MsgBox(ex.ToString)
End Try

End Sub



Bill McCarthy said:
Hi Michael,

If you can explicitly call Dispose, it is always best to do this as this
provides timely release of resources the object may be holding onto. If you
don't call Dispose, the GC will eventually collect them for you once they go out
of scope, but that may take some time, and system resources could get low if any
of the objects waiting to be collected are holding onto resources, such as
bitmaps, brushes, fonts, or just large objects that take up large amounts of
memory.
So, the general rule is if you can safely call IDisposable.Dispose on the
object, then do so.

HTH's

Bill.


Michael Hart said:
I have a form that creates new objects in all sorts of fashion using vb.net.

Some are created when the form opens with

Private varName as new Object()

just near the form class

In some subs I have

Sub Internal1()
Dim myVar as new Object()
End Sub

in the declaration section

and also sometimes I have the constructer separate to the declaration

Sub Internal2()
Dim newVar as Object

newVar = new Object(parm1, parm2)
End Sub

Do I need to explicitly dispose of these objects or will the garbage
collector [if there is one] take care of it when they go out of scope?

When I do a Me.Close on a form does it invoke the garbage collector on the
form?
 
B

Bill McCarthy

Hi Michael,

1. The form goes out of scope when you no longer have a reference to it.
Me.Close does not mean the form goes out of scope as such. If this is the root
form (startup form) for your app, then yes, me.close will typically close the
message loop and there will be no other references to the instance of the form.
But most importantly, Me.Close releases any system resources that the form held,
and actually calls the same Dispose code underneath.
So, yes, Me.Close does releases resources in a timely manner.


2. What Dispose actually does depends on the objects. For some objects it does
nothing, for others it signals to release numerous system resources the object
may be holding on to. It will vary from Type to Type. DataAdapters and
DataCommands for example don't actually hold onto any system resources other
than the actual data connection when it is open. So typically, calling dispose
on these kind of objects will mean they will just close the connection. For
datasets, there is no large un managed memory being held onto or system
resources, so Dispose on a dataset does nothing (I think <g>) significant. (it's
actually inherited from it's base class and just raises the disposed event and
removes the dataset from the finalization que)
So the goal of Dispose is not to remove the object itself from memory, but to
allow the object to release expensive/limited/ or system resources in a timely
manner.

Bill.





Michael Hart said:
Thanks Bill,

2 further quesitons

1..
Do form object go out of scope when you call Me.Close on the form? If not
how do you make a form go out of scope?


2..
How does this work? I have some data access objects that I declare in the
declaration section of a sub then .Dispose of but they are still accessable.
Note in particular the DataAdapter, Dataset, Command and Parameter objects
in the following code. I would have thought that if I free the memory for
these objects with the .Dispose method it would throw some sort of bounds
exception if I tried to use them again. This code works without errors
everytime I use it. Why doesn't Dispose clear the objects?

Private Sub GetC()
Dim sqlStr As String
Dim C As Double
Dim con As New OleDb.OleDbConnection()
Dim cmd As New OleDb.OleDbCommand()
Dim da As New OleDb.OleDbDataAdapter()
Dim ds As New DataSet()
Dim parm As New OleDb.OleDbParameter()

C = 0
Try
sqlStr = "SELECT [C_Value], [ID] FROM
WHERE ([ID]= ? )"

con.ConnectionString = ADB_strCon
cmd.Connection = con
cmd.CommandText = sqlStr
parm.Direction = ParameterDirection.Input
parm.DbType = DbType.String
parm.ParameterName = "?"
parm.Value = txtProvider1.Text
parm.Size = Len(txtProvider1.Text)
cmd.Parameters.Add(parm)

da.SelectCommand = cmd
da.Fill(ds, "C_Value")
C = C + ds.Tables("C_Value").Rows(0)(0)

ds.Clear()
ds.Dispose()
da.Dispose()
cmd.Parameters.Clear()
cmd.Dispose()

cmd.Connection = con
cmd.CommandText = sqlStr
parm.Value = txtProvider2.Text
parm.Size = Len(txtProvider2.Text)
cmd.Parameters.Add(parm)

da.SelectCommand = cmd
da.Fill(ds, "C_Value")
C = C + ds.Tables("C_Value").Rows(0)(0)

ds.Clear()
ds.Dispose()
da.Dispose()
cmd.Parameters.Clear()
cmd.Dispose()

cmd.Connection = con
cmd.CommandText = sqlStr
parm.Value = txtProvider3.Text
parm.Size = Len(txtProvider3.Text)
cmd.Parameters.Add(parm)

da.SelectCommand = cmd
da.Fill(ds, "C_Value")
C = C + ds.Tables("C_Value").Rows(0)(0)

ds.Clear()
ds.Dispose()
da.Dispose()
cmd.Parameters.Clear()
cmd.Dispose()

Catch ex As Exception
MsgBox(ex.ToString)
End Try

End Sub



Bill McCarthy said:
Hi Michael,

If you can explicitly call Dispose, it is always best to do this as this
provides timely release of resources the object may be holding onto. If you
don't call Dispose, the GC will eventually collect them for you once they go out
of scope, but that may take some time, and system resources could get low if any
of the objects waiting to be collected are holding onto resources, such as
bitmaps, brushes, fonts, or just large objects that take up large amounts of
memory.
So, the general rule is if you can safely call IDisposable.Dispose on the
object, then do so.

HTH's

Bill.


Michael Hart said:
I have a form that creates new objects in all sorts of fashion using vb.net.

Some are created when the form opens with

Private varName as new Object()

just near the form class

In some subs I have

Sub Internal1()
Dim myVar as new Object()
End Sub

in the declaration section

and also sometimes I have the constructer separate to the declaration

Sub Internal2()
Dim newVar as Object

newVar = new Object(parm1, parm2)
End Sub

Do I need to explicitly dispose of these objects or will the garbage
collector [if there is one] take care of it when they go out of scope?

When I do a Me.Close on a form does it invoke the garbage collector on the
form?
 
C

Cor

Hi Bill,

The opinion after long time of discussions in the dotnet newsgroups is now
in my opinion that calling dispose has only sence when it are non managed
resources and/or problem arrea's (or which has that in them) but absolutly
not always, it cost only extra processing time.

Cor
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top