by
Brendan >> Fri, 24 Jun 2005 8:33:53 GMT
In addition to the good advice from Allistar, there is the problem of finding where a leaky transient was created or, more precisely, should have been deleted.
There are two things which can help here. The first is the CardsSchema method app.cnCheckForTransients which searches for undeleted transient objects on shutdown and logs how many there were for each class. This tells you the scale of any transient leak problem you may have (if your users haven't alread
). The option is enabled via the CardSchema ini file option CheckTransientsOnShutDown=true. Note, however, that this was written long before PeerSchemas and Packages were introduced so there may be some other places to look as well.
If you have identified that there is a problem, it can be quite tricky in a large app to find where the transients should have been deleted. An approach I have used successfully on a number of projects in the past is two pronged. One is to to put some diagnostic code in the constructor and destructor methods of all transients in, say, a BaseTransient abstract superclass and one or two other places. The other is to reimplement createIterator on Collection (on Btree and List classes) so that you can get diagnostics when an iterator is created. (I couldn't fifure out a way to automatically get diagnostics when an iterator was deleted).
The diagnostic information I write out to a file is in the format
<oid> C <call stack>
for the create and
<oid> D
for the delete.
For iterators, the <oid> C <call stack> is written to a separate file.
Then the diagnostic file is sorted on the first two fields <oid> and [CD] (SortActor helps here) and a JadeScript goes through the file throwing away matching, consecutive <oid> C and <oid> D pairs. What you are left with is a list of all undeleted transients and the call stack indicating where they were created. This is usually enough to fix the problem.
You can filter which transients get diagnostics by switches and reimplementing the methods logging the dianostics so that the performance is acceptable when running in test mode.
For iterators, the oid of all undeleted iterators is logged and then you can easily find where it was created and what the call stack is.
Cheers, Brendan