Re: ado memory leak? - source provided

Tech-Archive recommends: Fix windows errors by optimizing your registry



Thanks for replying. I know there's not much in the description. I've run
the code using memory leak detectors (like Bounds Checker) and the CRT
debugging flags, but nothing is reported as leaked, so I don't know what's in
the leaked memory. The way in which it shows itself is a gradual and
consistent increase in memory usage. I've been using perfmon and tracking
'private bytes' of the process to see the leak.

I'm not sure how to see what might be leaking or what's in the memory that
is leaking without a tool that shows leaked memory blocks. I've investigated
an interface pointer leak, but that doesn't seem to be the case (I've called
AddRef() [and Release()] on the pointers to see if their reference counts are
as expected just before the object should go out of scope).

I've also been able to simply comment out the line that calls the Execute
method of the Command object and can see that the memory usage stops growing.

Do you have any further suggestions?

Thanks again.


"Scot T Brennecke" wrote:

> When tracking down a memory leak, it helps to know more clues than just "there's a leak". For
> instance, is it one big blob of memory, or several identical smaller ones. If many, how big are
> they? What type of memory allocation does it appear to be that's leaking? What clues can you get
> from the contents of the leaked memory blocks?
>
> "khalprin" <khalprin@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
> news:2EE2C086-5A16-425F-8167-BABB1E0D4ED4@xxxxxxxxxxxxxxxx
> > I'm trying to find a memory leak in my code that uses ADO and have a sample
> > that exhibits the leak. I started with some sample code from Matt Neerincx
> > (thank you) and modified it to resemble the way it is executed in my program
> > and a COM
> > component.
> >
> > The test includes a loop which:
> > 1. connects to the database (jet)
> > 2. executes a command to delete records from a table
> > 3. executes a command (3 times) to add a record to the table
> > 4. disconnects
> >
> > I've constructed the test using commands in stored procedures, and using
> > commands as text with and without parameters. Compiling each way results in
> > the leak. The code is below. Can anyone
> > point out the leak?
> >
> > Thanks.
> >
> >
> > #include "stdafx.h"
> > #include <atlbase.h>
> > //#include "Test2.h"
> > #include "conio.h"
> >
> > #pragma warning( push )
> > #pragma warning( disable : 4146 )
> > #import "c:\Program Files\Common Files\system\ado\msadox.dll"
> > #import "c:\Program Files\Common Files\system\ado\msado15.dll"
> > rename("EOF","EndOfFile")
> > #pragma warning( pop )
> >
> > #ifdef _DEBUG
> > #define new DEBUG_NEW
> > #undef THIS_FILE
> > static char THIS_FILE[] = __FILE__;
> > #endif
> >
> > //#define USE_CMDPROC
> > //#define USE_PARAMS
> >
> > void RunSample();
> > ADODB::_ConnectionPtr GetJetConnection();
> > void RunSingleLoop();
> > void Reset(ADODB::_ConnectionPtr conn);
> > void AddRecords(ADODB::_ConnectionPtr conn);
> >
> > /////////////////////////////////////////////////////////////////////////////
> > // The one and only application object
> >
> > CWinApp theApp;
> >
> > using namespace std;
> >
> > int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
> > {
> > int nRetCode = 0;
> >
> > // initialize MFC and print and error on failure
> > if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
> > {
> > // TODO: change error code to suit your needs
> > cerr << _T("Fatal Error: MFC initialization failed") << endl;
> > return -1;
> > }
> >
> > CoInitialize(NULL);
> > RunSample();
> > CoUninitialize();
> >
> > return nRetCode;
> > }
> >
> > #define LOOP_COUNT 100000 // Number of loops to execute.
> >
> > void RunSample()
> > {
> >
> > #if defined(USE_CMDPROC) && defined(USE_PARAMS)
> > #error ("Invalid configuration")
> > #endif
> >
> > ADODB::_ConnectionPtr global_conn = NULL;
> > int i;
> >
> > try
> > {
> > // Open global conn to keep Jet loaded (perf).
> > global_conn = GetJetConnection();
> >
> > try
> > {
> > global_conn->Execute(L"drop table
> > T1",NULL,ADODB::adExecuteNoRecords|ADODB::adCmdText);
> > }
> > catch ( _com_error ex )
> > {
> >
> > }
> >
> > global_conn->Execute(L"create table T1(f1 int, f2
> > int)",NULL,ADODB::adExecuteNoRecords|ADODB::adCmdText);
> >
> > for (i=1; i<=LOOP_COUNT; i++ )
> > {
> > RunSingleLoop();
> >
> > Sleep(5);
> > if ( 0 == (i%1000))
> > {
> > printf( "Completed %08lu of %08lu iterations.\n", i, LOOP_COUNT );
> > while ( _kbhit() )
> > {
> > int x = _getch();
> > if ( 'Q' == x || 'q' == x )
> > {
> > return;
> > }
> > }
> > }
> > }
> > }
> >
> > catch( _com_error ex )
> > {
> > // Robust error trapping left as an exercise for the reader. (G)
> > ASSERT(FALSE);
> > }
> >
> > return;
> > }
> >
> > _bstr_t JET_CONNECT(L"Provider=Microsoft.Jet.OLEDB.4.0;Data
> > Source=C:\\NW99.mdb;");
> >
> > ADODB::_ConnectionPtr GetJetConnection()
> > {
> > HRESULT hr;
> > ADODB::_ConnectionPtr conn = NULL;
> >
> > hr = conn.CreateInstance( __uuidof(ADODB::Connection) );
> > //if ( FAILED( hr ) ) throw( _com_error( hr, NULL ) );
> >
> > conn->CursorLocation = ADODB::adUseServer;
> >
> > // Open connection.
> > conn->Open( JET_CONNECT, "", "", -1L );
> > //Setting this property doesn't help.
> > //conn->Properties->Item["Jet OLEDB:Max Buffer Size"]->Value = 500L;
> >
> > return conn;
> > }
> >
> > void RunSingleLoop()
> > {
> > ADODB::_ConnectionPtr conn = NULL;
> >
> > // Open local conn for loop.
> > conn = GetJetConnection();
> >
> > Reset(conn);
> >
> > // The AddRecords generate the memory leaks
> > AddRecords(conn);
> > AddRecords(conn);
> > AddRecords(conn);
> >
> > conn->Close();
> > conn = NULL;
> > }
> >
> > void Reset(ADODB::_ConnectionPtr conn)
> > {
> > ADODB::_CommandPtr cmd = NULL;
> > CComVariant v1;
> >
> > HRESULT hr = cmd.CreateInstance( __uuidof(ADODB::Command) );
> >
> > /*
> > Query: qdMissingData
> >
> > PARAMETERS P1 Long;
> > DELETE * FROM T1 WHERE f1=P1;
> > */
> >
> > cmd->ActiveConnection = conn;
> > #ifdef USE_CMDPROC
> > cmd->CommandText = L"qdMissingData";
> > cmd->CommandType = ADODB::adCmdStoredProc;
> > #else
> > #ifdef USE_PARAMS
> > cmd->CommandText = L"DELETE * FROM T1 WHERE f1=?";
> > #else
> > cmd->CommandText = L"DELETE * FROM T1 WHERE f1=1";
> > #endif
> > cmd->CommandType = ADODB::adCmdText;
> > #endif
> >
> > #ifdef USE_PARAMS
> > v1 = 1L;
> > cmd->Parameters->Append(cmd->CreateParameter(
> > L"P1",ADODB::adInteger,ADODB::adParamInput,-1, v1));
> > v1.Clear();
> > #endif
> >
> > cmd->Execute(NULL,NULL,ADODB::adExecuteNoRecords);
> >
> > cmd->ActiveConnection = NULL;
> > cmd = NULL;
> > }
> >
> > void AddRecords(ADODB::_ConnectionPtr conn)
> > {
> > ADODB::_CommandPtr cmd = NULL;
> > CComVariant v1;
> > CComVariant v2;
> > static long lCounter = 1;
> >
> > // Now create parameterized ADO call.
> > HRESULT hr = cmd.CreateInstance( __uuidof(ADODB::Command) );
> > // if ( FAILED( hr ) ) throw( _com_error( hr, NULL ) );
> >
> > cmd->ActiveConnection = conn;
> >
> > /*
> > Query: qiMissingRecord:
> >
> > PARAMETERS P1 Long, P2 DateTime;
> > INSERT INTO T1 ( f1, f2 ) VALUES (P1, P2);
> > */
> >
> > // Create insert statement and setup params.
> > #ifdef USE_CMDPROC
> > cmd->CommandText = L"qiMissingRecord";
> > cmd->CommandType = ADODB::adCmdStoredProc;
> > #else
> > #ifdef USE_PARAMS
> > cmd->CommandText = L"INSERT INTO T1 ( f1, f2 ) VALUES (?, ?)";
> > #else
> > cmd->CommandText = L"INSERT INTO T1 ( f1, f2 ) VALUES (1, 2)";
> > #endif
> > cmd->CommandType = ADODB::adCmdText;
> > #endif
> >
> > #ifdef USE_PARAMS
> > v1 = 1L;
> > v2 = lCounter++;
> > cmd->Parameters->Append(cmd->CreateParameter(
> > L"P1",ADODB::adInteger,ADODB::adParamInput,-1, v1));
> > cmd->Parameters->Append(cmd->CreateParameter(
> > L"P2",ADODB::adInteger,ADODB::adParamInput,-1, v2));
> > v1.Clear();
> > v2.Clear();
> > #endif
> >
> > // Execute statement.
> > cmd->Execute(NULL,NULL,ADODB::adExecuteNoRecords);
> >
> > // Cleanup
> > cmd->ActiveConnection = NULL;
> > cmd = NULL;
> > }
> >
>
>
>
.



Relevant Pages

  • Re: [PATCH] replace various uses of num_physpages by totalram_pages
    ... The amount of what actually is usable as ... the memory hotplug code should update num_physpages ... #ifdef CONFIG_HIGHMEM ... void online_page ...
    (Linux-Kernel)
  • Re: MDAC memory leak
    ... Most libraries place the decision of when to free ... There's a capability of breaking on a particular memory allocation, ... leak 500 objects, on the second test I leak 3, because I fixed the bug). ... "App shows memory leak on some machines." ...
    (microsoft.public.vc.mfc)
  • Re: MDAC memory leak
    ... Also when we used some of the memory leak tools suggested on microsoft site ... A mutex is a considerably less efficient synchronization ... "App shows memory leak on some machines." ...
    (microsoft.public.vc.mfc)
  • Re: Help! define_method leaking procs...
    ... >>> VmSize value. ... there is no evidence yet that ruby is not ... I am not saying there is no memory leak ...
    (comp.lang.ruby)
  • Re: Memory leak in the Driver
    ... Paul G. Tobey wrote: ... driver development, it's most likely that you are at fault. ... The QFE has no impact on the leak but one thing is sure, ... i am sure that all the memory that i am allocating in my driver is ...
    (microsoft.public.windowsce.platbuilder)