|
-
Nov 14th, 2007, 09:56 PM
#1
Thread Starter
Frenzied Member
[2005] Memory Management
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?
-
Nov 14th, 2007, 10:10 PM
#2
Re: [2005] Memory Management
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.
-
Nov 14th, 2007, 11:39 PM
#3
Thread Starter
Frenzied Member
Re: [2005] Memory Management
So rather than just set an object to Nothing, I could pass my object to this:
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
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 ?
-
Nov 14th, 2007, 11:47 PM
#4
Re: [2005] Memory Management
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:
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 ?
has already been provided:
When you call the Dispose method of an object it will release both the managed and unmanaged resources that that object holds
The controls on a form are included in the form's managed resources.
-
Nov 14th, 2007, 11:50 PM
#5
Thread Starter
Frenzied Member
Re: [2005] Memory Management
 Originally Posted by jmcilhinney
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.
Yes. I just discovered that the DataTable class does not have an IsDisposed property so I amended the procedure to:
Code:
Public Sub DisposeObject(ByVal myObject As Object)
Try
myObject.Dispose()
Catch ex As Exception
Finally
myObject = Nothing
End Try
End Sub
-
Nov 15th, 2007, 12:14 AM
#6
Re: [2005] Memory Management
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.
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.
-
Nov 15th, 2007, 12:48 AM
#7
Thread Starter
Frenzied Member
Re: [2005] Memory Management
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:
Code:
Using myDataTable As New DataTable
End Using
Are you saying that the object's Dispose method is automatically called when the code reaches the End Using line?
-
Nov 15th, 2007, 01:00 AM
#8
Re: [2005] Memory Management
 Originally Posted by MSDN
vb.net Code:
' Insert the following line at the beginning of your source file.
Imports System.Data.SqlClient
Public Sub AccessSql(ByVal s As String)
Using sqc As New System.Data.SqlClient.SqlConnection(s)
MsgBox("Connected with string """ & sqc.ConnectionString & """")
End Using
End Sub
The system disposes of the resource no matter how you exit the block, including the case of an unhandled exception.
Note that you cannot access sqc from outside the Using block, because its scope is limited to the block.
You can use this same technique on a system resource such as a file handle or a COM wrapper. You use a Using block when you want to be sure to leave the resource available for other components after you have exited the Using block.
....
-
Nov 15th, 2007, 01:04 AM
#9
Thread Starter
Frenzied Member
Re: [2005] Memory Management
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?
-
Nov 15th, 2007, 01:19 AM
#10
Re: [2005] Memory Management
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.
-
Nov 15th, 2007, 01:23 AM
#11
Thread Starter
Frenzied Member
Re: [2005] Memory Management
I am asking whether a Dispose method can be added to a class that does not have one.
-
Nov 15th, 2007, 01:36 AM
#12
Re: [2005] Memory Management
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.
-
Nov 15th, 2007, 01:43 AM
#13
Re: [2005] Memory Management
I just re-read post #9. What exactly is it you're asking? Do you mean implement a Dispose method in this class:
When I create my own class, the class does not have a Dispose method.
or the type of this object:
If a global object is instantiated from this class
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.
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.
-
Nov 15th, 2007, 01:52 AM
#14
Thread Starter
Frenzied Member
Re: [2005] Memory Management
 Originally Posted by jmcilhinney
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.
A class automatically has an empty constructor and destructor.
I have added "Implements IDisposable" to my class and two overloaded Dispose methods were added to my class as follows:
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
What do I need to add to this to free the resources used by an object of the class?
-
Nov 15th, 2007, 01:58 AM
#15
Re: [2005] Memory Management
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.
-
Nov 15th, 2007, 02:39 AM
#16
Thread Starter
Frenzied Member
Re: [2005] Memory Management
 Originally Posted by robertx
the object has large properties such as images, byte arrays and large data tables
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:
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
-
Nov 15th, 2007, 06:52 AM
#17
Re: [2005] Memory Management
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.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|