Postby ConvertFromOldNGs » Fri Aug 07, 2009 12:14 pm
by cdshearer >> Tue, 5 Nov 2002 9:37:30 GMT
Hi Jens
I think you must have been a little tired as I couldn't make much sense of your message! But it did prompt me to think about things and do some investigation into a system I'm currently working on.
Here's some stuff I discovered:
1. You have to write your own routine to check for undeleted transients - typically you'd call this from your Application::finalize method. There is some sample code in the FAQ section of the JADE web site.
2. The provided sample code actually only checks for undeleted transients of classes in your schema - it doesn't check for transient instances of classes from other schemas. So, if you happen to have created some RootSchema transients, then these won't be detected by this code. Below, I've put some better code.
3. JADE's own code isn't necessarily squeaky clean. I found that the Schema Inspector leaks transient instances of the ClassColl class. Admittedly, you're unlikely to use this in a production application.
4. Watch out for how you use some of JADE's methods, as some of them are misleadingly documented. For example, the Class::allProperties method is documented as "returns a reference to..." a collection of properties. When in fact it actually creates a transient collection for you, populates it and passes it back. So, you're responsible for putting the returned reference in a variable and deleting it later. If you do the following, you'll leak transients:
foreach property in class.allProperties() do
// Deal with the property
endforeach;
The correct way to code this is:
vars
properties : PropertyColl;
property : Property;begin
properties := class.allProperties();
foreach property in properties do
// Deal with the property
endforeach;
epilog
delete properties;
end;
5. Once you've identified that you have a leak, it can be very difficult to track it down. So, I would suggest that you run the check code frequently, so that if fresh undeleted transients start to appear, it must be in code you've recently written or modified. For a GUI app, it can help to have some way of triggering a dump of the current transient instances, so that you monitor transient instances at strategic places in your app's execution.
Finally, here's the code for detecting undeleted transients across all schemas for a process:
vars
insts : ObjectArray;
obj : Object;begin
create insts transient;
Object.allProcessTransientInstances(insts, 0, true);
foreach obj in insts do
write obj.String;
endforeach;
epilog
delete insts;
end;
Note that the above code will detect some legitimate transient instances. For example, it will detect the Application instance, and also the actual ObjectArray that is being populated, as well as some other transient instances hanging off app. You could modify the above code to filter out these known transients.
The above code does take some time to execute, so you might want to have a way of switching it on and off, otherwise your app takes an extended time to shut down.
Hope this helps...
Craig