Search This Blog

Saturday, June 30, 2012

Cross, Circular Reference in VBA

Particular care should be used in VBA when we run into a cross-reference, also called circular-reference.

Let's suppose that we have a collection Knots of Knot objects

Dim col as Knots
Dim n as knot

Set col = new Knots
Set n = new Knot
Set n.Parent = col

Set col = Nothing



If we count the reference to the Knots object untill we reach the Set n.Parent = col line, we can see that the sum to 2.
Both col and n.Parent refers to a Knots object in menory.
The new keyword creates the object in memory, a brand new one. The Set n.Parent = Col make the counter to this reference to increment by 1. VBA keeps a counter of each object reference  and it deallocates the momory used by it only if it reaches 0. Each time we use Set col = Nothing VBA reduce the counter by 1, but it will free the memory only when this counter reaches 0.
So if we just set col = Nothing, we will fail to free the memory from the object. The Reference counter will be 1 instead of 0, so VBA will not free memory for it.
If a collection of knots holds n knot objects, this collection will have n+1 reference and they all need to cleaned up to have the memory free from any leaks.
To work around this problem we must make sure that each knot object set its parent property to nothing when is terminated. We can do this creating Terminate sub. For the Knots class  we need to create a  another Terminate methods that will loop each element of the collection to call the knot Terminate() sub.
Please note that if instead we call Set Knot = Nothing, this will not clear the memory.

'For the knot Class
Public Sub Terminate()

   Set Me.Parent = Nothing

End Sub

'For the knots Class
Public Sub Terminate()

  For Each Knot in Knots
    Call knot.Terminate() 

  Next
  Set mCol = Nothing
End Sub




With the addition of these to Terminate Class events, we make sure that all reference to the Knots class coming from its items are terminate, so we don'have any memory leak. Please note that we need to explicitly call the Terminate() method of the knots class before setting knots = Nothing

No comments:

Post a Comment