[AccessD] Tracking down memory leak

McGillivray, Don [IT] Donald.A.McGillivray at sprint.com
Thu Jan 22 14:52:59 CST 2009


Thanks, John.  I'm adding RS.Close to the exit substructures where needed.  I think it's pretty rare in this app for it to error prior to closing the recordsets, but this will at least cover that base.

Don

-----Original Message-----
From: accessd-bounces at databaseadvisors.com [mailto:accessd-bounces at databaseadvisors.com] On Behalf Of jwcolby
Sent: Thursday, January 22, 2009 11:44 AM
To: Access Developers discussion and problem solving
Subject: Re: [AccessD] Tracking down memory leak

 >So I suppose I should place additional .Close statements
(preceded by On Error Resume Next) in my Exit substructure
to ensure that they are always called.

This should always be done.  There should always be a common
exit point and that exit point should always be called to
get out of the function.  Then all cleanup code goes there,
preceded by On Error resume next.



John W. Colby
www.ColbyConsulting.com


McGillivray, Don [IT] wrote:
> Thanks, John.
>
> I should have mentioned that I have also made sure that all recordsets are explicitly closed before being set to nothing.  However, it occurs to me that those .Close statements are always within the body of the procedure.  If the proc encounters an error before the .Close is called, I suppose it may fail to close before setting the related recordset to Nothing.  So I suppose I should place additional .Close statements (preceded by On Error Resume Next) in my Exit substructure to ensure that they are always called.
>
> I'll check out the possibility of multiple pointers to the same object, but I don't think I'm using that technique anywhere in the app.
>
> As for bound forms, this app has one form whose purpose is to maintain a link to the back end DB, and another that has two bound list boxes, but no other bound controls.  In case it may matter to the question of memory leak, the app is designed as a sort of daemon.  It gets started and is left to run on its own.  It's controlled by the OnTimer event of the main form.  Essentially, clicking the start button on the main form sets the TimerInterval to 1, causing the OnTimer event to fire.  A bunch of processing happens, after which the TimerInterval is set to 15 seconds, allowing user intervention if necessary (to stop the app, for example).  At the end of the 15 seconds, the timer fires and the process runs again, and so on until manually interrupted.  Often the app will run for days or weeks without interruption.  The process gathers data stored in text files created by other systems, storing metadata related to those files as well as summaries of the files' contents.  The
pr!
>  ocess also manages a "job queue" that is populated by users from other systems.  The job queues contain instructions for performing file system tasks such as moving files between servers and archiving, deleting, and restoring files.
>
> Don
>
> -----Original Message-----
> From: accessd-bounces at databaseadvisors.com [mailto:accessd-bounces at databaseadvisors.com] On Behalf Of jwcolby
> Sent: Thursday, January 22, 2009 10:58 AM
> To: Access Developers discussion and problem solving
> Subject: Re: [AccessD] Tracking down memory leak
>
> First of all you must CLOSE all recordsets.
>
> Next, you need to make sure you are not copying a pointer to
> a recordset to another variable.  An object is not destroyed
> until the LAST pointer to the object is set to nothing.  IOW
> if I create a recordset, then pass the recordset off to
> another piece of code, and that piece of code STORES the
> pointer, now I have TWO pointers to the recordset.  BOTH
> pointers have to be set to nothing before the object is
> destroyed.
>
> And finally, understand that every bound form, combo, list
> etc uses a DAO recordset.  Basically anything that uses a
> table or query.  Thus a form with 20 combos has at least 21
> recordsets opened.
>
> John W. Colby
> www.ColbyConsulting.com
>
>
> McGillivray, Don [IT] wrote:
>> Hi, All
>>
>> I'm looking for guidance on identifying the source of a memory leak in an application.  I've already gone through my code to ensure that each "Set ObjVariable =  . . . " statement is accompanied by a "Set ObjVariable = Nothing" statement.  All my procedures use error handling, and are forced to exit through a substructure that contains the proc's "Set ObjVariable = Nothing" statements, ensuring that the object variables are set to nothing even when an error occurs.
>>
>> As the app runs, both memory usage and the handle count slowly creep up over time - the handle count faster than the memory usage.
>>
>> I did a simple experiment by monitoring handle usage while opening and closing a single table in a database several times.  I noticed that at first the handle usage was variable, but that after several repetitions it more or less stabilized.  Something like this:
>>
>> Rep             State           Handles
>> =================================
>> 0               Initial 195
>> 1               Open            203
>> 1               Closed  199
>> 2               Open            203
>> 2               Closed  200
>> 3               Open            202
>> 3               Closed  200
>> 4               Open            201
>> 4               Closed  200
>> 5               Open            210
>> 5               Closed  204
>> 6               Open            207
>> 6               Closed  204
>> 7               Open            206
>> 7               Closed  201
>> 8               Open            204
>> 8               Closed  201
>> 9               Open            204
>> 9               Closed  201
>>
>> For grins, I left the db open and idle overnight.  When I checked this morning, its memory usage had gone from 20.7 MB to 3.7 MB.  Upon opening the table, the usage went to 7.8 MB and stayed around there after several open/close repetitions.
>>
>> So, now I'm more confused than when I started.  How exactly does one detect memory leak, and once detected, how to find its source?
>>
>> Anybody out there with nothing better to do than to educate my weak brain?
>>
>> Don
>>
>> This e-mail may contain Sprint Nextel Company proprietary information intended for the sole use of the recipient(s). Any use by others is prohibited. If you are not the intended recipient, please contact the sender and delete all copies of the message.
>>
>>
> --
> AccessD mailing list
> AccessD at databaseadvisors.com
> http://databaseadvisors.com/mailman/listinfo/accessd
> Website: http://www.databaseadvisors.com
>
>
> This e-mail may contain Sprint Nextel Company proprietary information intended for the sole use of the recipient(s). Any use by others is prohibited. If you are not the intended recipient, please contact the sender and delete all copies of the message.
>
>
--
AccessD mailing list
AccessD at databaseadvisors.com
http://databaseadvisors.com/mailman/listinfo/accessd
Website: http://www.databaseadvisors.com


This e-mail may contain Sprint Nextel Company proprietary information intended for the sole use of the recipient(s). Any use by others is prohibited. If you are not the intended recipient, please contact the sender and delete all copies of the message.





More information about the AccessD mailing list