FoxPro Programming
Understanding Hung Objects
Gravatar is a globally recognized avatar based on your email address. Understanding Hung Objects
  Harvey Mushman
  All
  Sep 11, 2019 @ 12:21pm

In the image below I reference an article you wrote back in 2008 titled Detecting hung Objects in Visual Forpro. In that article you show a fairly specific example of how to destroy objects so they con't hang. I'm trying to be sure I clearly understand how this might be caused.

In my image below, I show my understand in a block diagram and then in VFP code.

  1. Is my example a correct understanding of what causes objects to hang?

  2. If the property "vResult" (which is commented out in the DoSomething function) was used to pass back the "Y" object, I assume the EMPTY object along with its PK property would not hang when oX is released?

Thnaks for any comments

Gravatar is a globally recognized avatar based on your email address. re: Understanding Hung Objects
  Rick Strahl
  Harvey Mushman
  Sep 13, 2019 @ 01:43pm

In your example, if your release oX you will effectively clear and garbage collect that object instance and then when you release oY it will cleanly release, because the reference of the object is released with it. Releasing the object instance explicitly in one place will not necessarily clear it everywhere.

The best rule of thumb for proper cleanup is that any dependent object that takes a reference to another object should be responsible for clearing that object. IOW, make sure you clear all child references before clearing the parent reference.

The most common scenario is what you describe but in reverse: You create a child object that has a reference to a parent object, and then the parent releases the second object that holds the child reference. At that point that second object becomes locked because it can't release the child object to the parent since it's still alive and active.

The way to fix that is to have a Dispose() style method you call that cleans up the object, or implement a Destroy handler that explicitly nulls out object references. The problem with Deploy in VFP is that the rules on when that fires exactly is very nebulous. It only fires when all instances that are referenced are cleared, so for object cleanup this may not always fire when you think.

One piece of advice is: try to minimize the use of nested object references that are passed in and if you do excplicitly clear them.

As the post you reference points out circular refs are a pain in the butt to debug mainly because they are not a problem until there are a lot of them. So in typical dev scenarios you never know you have this problem and the debugging tools in VFP are inadequate to actually show you outstanding references. The only thing that does is DISPLAY MEMORY and that also doesn't work with everything.

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: Understanding Hung Objects
  Harvey Mushman
  Rick Strahl
  Sep 16, 2019 @ 02:18pm

I reviewed this with Zak to get an even better understanding, and helped me to correct the drawing (see below). The sample VFP code shown below reflects my understanding.

I added a Dispose() method as you suggested to null out the object that was created within the parent object. I'm assuming from your prior answer having object variables (setting to NULL) in the DESTROY() event is not a good practice.

Does this look more better ...(it only took a PhD to explain it!)

DEBUG 
SUSPEND 
loX = CREATEOBJECT("X")
loY = loX.DoSomething()

? VARTYPE(loX.loXY) && display O

loX.Dispose()

? VARTYPE(loX.loXY) && display X

**************************************
**************************************
DEFINE CLASS X AS CUSTOM
 loXY = .null.
 * add a method
 ********************
 ********************
  FUNCTION DoSomething()
   this.loXY = CREATEOBJECT("Empty")
   RETURN this.loXY
  ENDFUNC
 ********************
 ********************
 FUNCTION Dispose()
  this.loXY = .null.
  RETURN .t. 
 ENDFUNC
 ********************
 ********************
ENDDEFINE
**************************************
**************************************
Gravatar is a globally recognized avatar based on your email address. re: Understanding Hung Objects
  Rick Strahl
  Harvey Mushman
  Sep 16, 2019 @ 11:28pm

I think so - hard to tell with your diagram.

The idea is basically if you set a reference to another object in a parent object - always have a way to explicitly clean up that reference to make sure all dependencies are released. It's not always a problem but in some situations - especially when there are multiple chained dependencies that this becomes a problem.

It's safe to set an object reference that's a one way reference - the garbage collector can deal with that just fine. it's only when the links go both ways:

This sort of thing:

child-> Parent -> child

if child releases parent you'll have a hung reference. If parent releases child - no problem.

In the WebControl framework this sort of thing was very common where a parent form references each child control in a collection, and each child control has a reference back to the parent. In that case you to have each child have dispose method that clears the parent before getting released.

A good garbage collector can deal with stuff like that - .NET, JavaScript and most other modern engines can because they do a better job of reference counting, but Fox has problems with that sort of thing.

+++ Rick ---

© 1996-2019