New thread continued from here:
http://www.vbforums.com/showthread.p...39#post3057939
Are you saying that calling the Dispose method invokes the GC and is tantamount to freeing the memory that is occupied by the object itself?
Printable View
New thread continued from here:
http://www.vbforums.com/showthread.p...39#post3057939
Are you saying that calling the Dispose method invokes the GC and is tantamount to freeing the memory that is occupied by the object itself?
An object can hold unmanaged resources directly, which means window handles, file handles or the like, or it can hold managed resources. A managed resource is just a managed object that itself holds managed or unmanaged resources.
When you call the Dispose method of an object it will release both the managed and unmanaged resources that that object holds, assuming that it's been implemented properly. That's all. It has nothing to do with the memory occupied by the object. The only other thing it does is tell the GC to suppress the object's Finalize method.
When the Framework decides that it needs the memory it will invoke the GC, which will then go out and reclaim the memory occupied by objects that no loger have any variables referring to them. because you disposed your object the GC will not call its Finalize method and it will simply mark the memory the object occupied as available to be allocated.
If you hadn't disposed the object then the GC would have had to call its Finalize method. That would invoke the Dispose method, which would then release any unmanaged resources. When it is invoked from the Finalize method Dispose will not try to release any managed resources because there's no guarantee that those objects haven't already been cleaned up by the GC. Once that's done, then the GC can reclaim the memory occupied by the object.
Hopefully this illustrates that by not disposing objects that support it you are not only monopolising valuable system resources longer than is necessary, you are also making the garbage collection mechanism less efficient.
So rather than just set an object to Nothing, I could pass my object to this:
If a form object is disposed, does that automatically dispose of all of the indisposed objects that belong to that form or do they need to be disposed of individually ?Code:Public Sub DisposeObject(ByVal myObject As Object)
Try
If myObject.IsDisposed = False Then myObject.Dispose()
Catch ex As Exception
Finally
myObject = Nothing
End Try
End Sub
Firstly, not all disposable objects have an IsDisposed property. IsDisposed is not a member of IDisposable. It's a member of the Control class, added so that you can check whether a control is disposed before calling its Show method.
There's no need to test whether an object has already been disposed before disposing it. The Dispose method is intentionally implemented such that calling it multiple times has no ill-effects.
The answer to this question:has already been provided:Quote:
If a form object is disposed, does that automatically dispose of all of the indisposed objects that belong to that form or do they need to be disposed of individually ?
The controls on a form are included in the form's managed resources.Quote:
When you call the Dispose method of an object it will release both the managed and unmanaged resources that that object holds
Yes. I just discovered that the DataTable class does not have an IsDisposed property so I amended the procedure to:Quote:
Originally Posted by jmcilhinney
Code:Public Sub DisposeObject(ByVal myObject As Object)
Try
myObject.Dispose()
Catch ex As Exception
Finally
myObject = Nothing
End Try
End Sub
You shouldn't be using an exception handler because no properly implemented Dispose method should ever throw an exception. Two more things with regard to that method:
1. This is pointless:The parameter is passed by value so setting it to Nothing can't have any effect on the original variable, which was covered in that other thread. Further, the parameter variable loses scope immediately after, so it ceases to exist. The only reason to set a variable to Nothing is if you specifically want to test it for Nothing at some point, or else it will not (or may not) lose scope for some time.vb.net Code:
myObject = Nothing
2. The Object type has no Dispose method so that code is relying on late-binding. If you added the exception handler just to allow for that then that's sloppy code. You would declare the argument as type IDisposable, which does have a Dispose method, which also ensures that no objects without a Dispose method are passed.
All that said, that method just doesn't serve a purpose. Just call the object's Dispose method where and when you're finished with the object if said object has a Dispose method. Better yet, for local variables whose type implements IDisposable you should be making use of Using blocks, which exist solely to support object disposal and implicitly dispose an object when the block completes.
Yes that was the only reason for the handler and I can see now that this is waste of time.
So if I declare an object using a Using statement:
Are you saying that the object's Dispose method is automatically called when the code reaches the End Using line?Code:Using myDataTable As New DataTable
End Using
....Quote:
Originally Posted by MSDN
Good.
When I create my own class, the class does not have a Dispose method. If a global object is instantiated from this class and is repeatedly set to nothing and reinitialised and the object has large properties such as images, byte arrays and large data tables, could this potentially cause a memory leak? Can a Dispose method be implemented for such a class?
What have I said all along? A Dispose method releases unmanaged and managed resources. If your object holds unmanaged or managed resources then it MUST implement its own Dispose method.
I am asking whether a Dispose method can be added to a class that does not have one.
No class automatically has a Dispose method. In fact, no class has any members at all until you add them. If YOUR class holds unmanaged or managed resources then it's YOUR responsibility, as the developer, to implement the IDisposable interface in YOUR class and, as a consequence, implement a Dispose method. If you don't then your software is faulty. In that case the resources held by your object will sit around unused and unavailable until the GC gets around to Finalizing those objects.
I just re-read post #9. What exactly is it you're asking? Do you mean implement a Dispose method in this class:or the type of this object:Quote:
When I create my own class, the class does not have a Dispose method.
You can't add methods to an existing class without inheriting the class. If you derived your own class from an existing class then you can add a Dispose method (obviously, because the Control class implements IDisposable while Object does not) but that's no use if the base class holds resources that you cannot access directly to release. In that case the base is just badly implemented and you shouldn't use it at all.Quote:
If a global object is instantiated from this class
Also, there's no such thing as global objects and you cannot set an object to Nothing. It's important to use the correct terminology to make sure you understand exactly what you're dealing with. Variables can be global and you can set a variable to Nothing. Objects can be created and assigned to variables. A variable can refer to an object or Nothing. An object cannot be nothing because it's an object, so it's something.
A class automatically has an empty constructor and destructor.Quote:
Originally Posted by jmcilhinney
I have added "Implements IDisposable" to my class and two overloaded Dispose methods were added to my class as follows:
What do I need to add to this to free the resources used by an object of the class?Code:Private disposedValue As Boolean = False ' To detect redundant calls
' IDisposable
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
' TODO: free unmanaged resources when explicitly called
End If
' TODO: free shared unmanaged resources
End If
Me.disposedValue = True
End Sub
#Region " IDisposable Support "
' This code added by Visual Basic to correctly implement the disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
I have no idea what resources your object holds, so how can I tell you how to release them? The MSDN library has plenty of information on implementing Dispose and Finalize methods. I suggest that you read it.
In post 9, I referred to a class which has images, byte arrays and data tables amongst its members. The Image and DataTable classes have a Dispose method. Do I simply have to call the Dispose method of these objects as follows:Quote:
Originally Posted by robertx
Code:Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
m_myImage.Dispose
m_myDataTable.Dispose
End If
' TODO: free shared unmanaged resources
End If
Me.disposedValue = True
End Sub
What have I been saying all along? The Dispose method releases resources.
What do you want to do? Release resources.
How do you do it? Call the Dispose method.