🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.database.ms-access
Article #5

Re: ADO Memory Leak - Please Help

#5
From: Roy Fine
Date: Fri, 12 Jul 2002 22:05
163 lines
7607 bytes
Paul

what you are most likely seeing is not a classic "memory leak", else you
would never regain the memory when closing the connection -- if it were
truly "leaked", it would only be freed when the OS cleaned up during process
termination.  ADO is implemented on OLEDB, and OLEDB providers (should) use
IMalloc for all dynamic memory allocation.  You can can implement
IMallocSpy, and in the PreAlloc and PostFree methods you can maintain a list
of allocated blocks.  You can also implement PreHeapMinimize to see how
often and under what conditions the memory manager cleans up and takes out
the garbage.

I think you will see that the OLEDB rowset data is held and not released
until either :
1) the session is closed, or
2) a call ot Alloc fails.

For your case - especially if you are concerned with performance, discard
the Recordset and implement the rowset additions using a parameterized,
persistent and prepared SQL Insert with the ADO::Command and ADO::Parameter
objects..  Opening any sort of Recordset just to do an insert or update is
typically the wrong way to go about the add/update.

Contrary to what others in this thread has suggested, do not take the route
of open/close the connection every time you need to do the add or update.
Creating a session object is very resource intensive, do it once and save
it -- they are meant to be persistent over a period of time.  (Connection
object like to celebrate birthdays too!)

best regards,
roy fine







"Paul Maia" <pmaia@austin.rr.com> wrote in message
news:n8pX8.99782$q53.2352660@twister.austin.rr.com...
> I appeal to the community for help... for I have failed...
>
> I have beaten my head against a wall trying to find the problem and
> have come up blank. I have an application that writes an Access
> database record about every 3-4 seconds. After running for several
> days I looked at Task Manager and noticed that it was consuming
> memory with every 3-4 records written (task manager only seems to
> have a 1-2k granularity). I have updated MDAC to 2.62 SP2 and
> Jet 4.0 Database to SP6 and the memory creep continues.
>
> I am fairly sure that it is something I am doing, but I am not familiar
> enough with the ADO API's to know the hidden secrets, yet. Any
> help would be greatly appreciated.
>
> The following code has the exception handling removed to simplify
> the post.With logging in each of the exception handlers, I have
> determined that there are no exceptions occurring.
>
> The code below is in a VC++ 6.0 (latest SP) DLL, that is called from
> C++ Builder.
>
> The DATABASE_HANDLE looks like...
>
> -----------------------------------------------------------
> typedef struct DATABASE_HANDLE
> {
>     ADODB::_ConnectionPtr conRef;
>     char databaseDSN[MAX_STRING];
>     char userID[MAX_STRING];
>     char password[MAX_STRING];
>     long ADO_ErrorIdx;
>     char *curErrMessage;
> } DATABASE_HANDLE;
> -----------------------------------------------------------
>
> I open the Database and leave it open (for weeks), writing the data to the
> database. Even if there was a leak in it, it would not (I hope) contribute
> to
> the leak that occurs on each addition to the database. Even though, if I
> close
> and re-open it, the previous creep level is the new starting point.
>
> But, for completeness, here is a snippet of the code to open the database:
>
> -----------------------------------------------------------
>         // initialize the connection object
>         dbHandle->conRef = NULL;
>
(void)dbHandle->conRef.CreateInstance(__uuidof(ADODB::Connection));
>         // make sure it is opened read/write
>         dbHandle->conRef->Mode = ADODB::adModeReadWrite;
>         // (default)
>         //  only allow viewing of transactions, once they are committed
>         dbHandle->conRef->IsolationLevel = ADODB::adXactCursorStability;
>         // set the attributes, no attributes
>         dbHandle->conRef->Attributes = 0;
>         // save the DSN
>         strncpy(dbHandle->databaseDSN, databaseDSN, MAX_STRING);
>         // open the database
>         (void)dbHandle->conRef->Open(databaseDSN, userID, password,
>             ADODB::adConnectUnspecified);
>
> -----------------------------------------------------------
>
> -----------------------------------------------------------
> ADOWRITE_API BOOL ADO_AddNewRecordToDatabase(DATABASE_HANDLE *dbHandle,
>     const char * const tableName, const char * const fields[],
>     const char * const values[], int itemCount)
> {
>     ADODB::_RecordsetPtr recRef = NULL;
>     BOOL retCode = FALSE;
>
>     // now add a record to the database
>     if (dbHandle->conRef->State == (int)ADODB::adStateOpen)
>     {
>         int x;
>         (void)recRef.CreateInstance(__uuidof(ADODB::Recordset));
>         // since we are only adding records here,
>         //  a forward -only cursor would be the fastest
>         recRef->CursorType = ADODB::adOpenForwardOnly;
>         // open the recordSet
>         (void)recRef->Open(tableName,
>             _variant_t((IDispatch *)dbHandle->conRef, true),
>             ADODB::adOpenKeyset, ADODB::adLockOptimistic,
>             (int)ADODB::adCmdTable);
>         // create a new data record
>         (void)recRef->AddNew();
>         // add the fields/values
>         for (x = 0; x < itemCount; x++)
>         {
>             (void)recRef->Fields->GetItem(_variant_t(fields[x]))->
>                  put_Value(_variant_t(values[x]));
>         }
>         // update it to the database
>         (void)recRef->Update();
>         // it's there
>         retCode = TRUE;
>         // close the recordset
>         (void)recRef->Close();
>         // free the recordset
>         recRef = NULL;
>     }
>     else
>     {   // add as a local message
>         AddLogEntry("[ADO_AddNewRecordToDatabase] "
>             "ConRef->State Does Not Show The Database Open");
>     }
>     // clear all errors
>     (void)dbHandle->conRef->Errors->Clear();
>     // return to caller
>     return(retCode);
> }
> -----------------------------------------------------------
>
> Your consideration is greatly appreciated,
>
> Paul Maia
> paul_maia@hotmail.no^^spam.com
> remove no^^spam to reply
>
>
>
>
Technical Details
Message-ID: <uuqNdAfKCHA.2604@tkmsftngp08>
Path: arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!sn-xit-02!sn-xit-01!sn-xit-08!supernews.com!isdnet!195.25.12.36.MISMATCH!oleane.net!oleane!fr.clara.net!heighliner.fr.clara.net!newsfeed01.sul.t-online.de!newsfeed00.sul.t-online.de!t-online.de!tkmsftngp01!tkmsftngp08
References: <n8pX8.99782$q53.2352660@twister.austin.rr.com>

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: 10845c,cc8cadb3e8b391c0
X-Google-Attributes: gid10845c,public
X-Google-Thread: 103747,cc8cadb3e8b391c0
X-Google-Attributes: gid103747,public
X-Google-Thread: 10698b,cc8cadb3e8b391c0
X-Google-Attributes: gid10698b,public
X-Google-Thread: f64f7,cc8cadb3e8b391c0
X-Google-Attributes: gidf64f7,public
X-Google-ArrivalTime: 2002-07-12 15:11:20 PST
From: "Roy Fine" <rlfine@sfa2000.com>
References: <n8pX8.99782$q53.2352660@twister.austin.rr.com>
Subject: Re: ADO Memory Leak - Please Help
Date: Fri, 12 Jul 2002 18:05:26 -0400
Lines: 165
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2600.0000
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2600.0000
Message-ID: <uuqNdAfKCHA.2604@tkmsftngp08>
Newsgroups: comp.database.ms-access,microsoft.public.data.ado,microsoft.public.vc.database,borland.public.cppbuilder.database.ado
NNTP-Posting-Host: 66.162.225.19
Path: arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!sn-xit-02!sn-xit-01!sn-xit-08!supernews.com!isdnet!195.25.12.36.MISMATCH!oleane.net!oleane!fr.clara.net!heighliner.fr.clara.net!newsfeed01.sul.t-online.de!newsfeed00.sul.t-online.de!t-online.de!tkmsftngp01!tkmsftngp08