Instantiation, parameters and the GC

mandelbrot

Centurion
Joined
Jul 1, 2005
Messages
194
Location
UK North East
Just a quick one...

If I declare an object as an argument for an expression in the form:
Visual Basic:
myVar = AnObject.Method([color=red]New MyClass()[/color])
Does the object finalise as soon as we drop out of the enclosing function/method?


Paul.
 
If it is an object that has to be disposed (it implements IDisposable) then you really need to keep a reference to it and call the Dispose method.

If the object does not need to be disposed then this is not a big deal. The garbage collector can do its thing. If this is code that will be called a lot (each time a button is clicked is not alot, but maybe if it is done hundreds of times each time the button is clicked) and it is something that is relatively easy to optimize (maybe you can keep a reference to an object and re-use it instead of instantiating one each time, for example) then you might consider using another scheme, but in general I wouldn't worry about it much.

It is amazing how many objects are created while your program is running. Relatively simple string manipulation can pump out dozens of objects. Every time an event is raised an object is created to pass information (your "e as EventArgs"). One more object here or there is really nothing.
 
Thanks for that, marble - it does explain a lot, most of which (when I think about it!) I already actually knew.

What I tend to do with my own classes is to provide the facility to Finalize them, thus allowing the GC to clean them up quicker. I know that for simple objects this isn't really necessary, but I'd rather be able to ensure that the memory's going to be tidy than have to wait for the GC to do its detective work.

Here's something for your trouble, marble, but remember - chew your food! ;)
 

Attachments

If your class doesn't have any non-mananged resources then implementing a finaliser will actually cause your class to take longer to be freed up.

As a rule if you are dealing with non-managed resources you should implement both IDisposable (correct way to clean up) and a Finaliser (a backup plan for those people who do not call Dispose). For any other type of class just leave the GC to do it's thing.
 
Last edited:
Ok - what I tend to do is see if MyBase.Finalise() is available and call this from the Dispose method (obviously checking to see if it's been called already).

So, as an example, I have a container class for IDataParameters that I pass to certain shared methods in a class I use frequently. I have created a Dispose method in this class as it provides a base Finalization routine. Is this right or wrong?...
Visual Basic:
    'Parameter class...
    Public Class Parameters
        Inherits System.Collections.CollectionBase

        'Disposed flag for the class...
        Private isDisposed As Boolean

        'Constructors...
        Public Sub New()
            'This constructor does nothing...
        End Sub
        Public Sub New(ByVal pParam As String, ByVal pValue As Object)
            'Dimensions...
            Dim tempParam As IDataParameter
            Select Case Data.Mode
                Case DataModes.modeDefault, DataModes.modeSqlServer
                    tempParam = New SqlParameter(pParam, pValue)
                Case DataModes.modeOleDb
                    tempParam = New OleDb.OleDbParameter(pParam, pValue)
            End Select
            list.Add(tempParam)
        End Sub

        'Allow addition of new parameter...
        Public Sub Add(ByVal paramProperty As IDataParameter)
            list.Add(paramProperty)
        End Sub
        Public Sub Add(ByVal pName As String, ByVal pValue As Object)
            Dim tempParam As IDataParameter
            If Data.Mode = DataModes.modeDefault Or Data.Mode = DataModes.modeSqlServer Then
                tempParam = New SqlParameter(pName, pValue)
            ElseIf Data.Mode = DataModes.modeOleDb Then
                tempParam = New OleDbParameter(pName, pValue)
            Else
                Throw New Exception("XML options not supported")
            End If
            list.Add(tempParam)
        End Sub

        'Remove existing properties...
        Public Sub Remove(ByVal pIndex As Int32)
            'Just make sure...
            If pIndex >= 0 And pIndex < list.Count Then
                list.RemoveAt(pIndex)
            Else
                Throw New IndexOutOfRangeException("pValues in the range: 0 - " & list.Count - 1)
            End If
        End Sub
        Public Sub Remove(ByVal pParam As IDataParameter)
            list.Remove(pParam)
        End Sub

        'Destructor...
        Public Sub Dispose()
            If Not isDisposed Then
                MyBase.Finalize()
                isDisposed = True
            End If
        End Sub

    End Class


Paul.
 
All objects provide a Finalize() method as it is inherited from System.Object.Finalize(), the CLR however ignores that version and will only act on methods declared in derived classes.

If the base class doesn't require any explicit clean up (which CollectionBase doesn't - a good thing to check is if it implements IDisposable) then neither does your class.

Also if you are going to provide a Dispose method you should really implement the IDisposable interface rather than just provide a method called Dispose().
 
Back
Top