Re: ADODB Command memory leak
- From: "khalprin" <khalprin@xxxxxxxxxxxxxxxxxxxxxxxxx>
- Date: Tue, 23 Aug 2005 10:13:16 -0700
Matt,
I started with your code and modified it to (somewhat) closely represent
what I'm doing, and was able to re-produce the leak. Can you see where the
problem is?
My data access code is in a COM component, so I broke it out into functions
in this test program. There are two simple queries used, and they're
included in the comments. I just noticed that one of the queries actually
expects a parameter as a DateTime type, and this test program is passing it a
long - seems to work though.
Thanks,
Ken
// Test2.cpp : Defines the entry point for the console application.
//
#include "stdafx.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
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()
{
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(0);
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 );
return conn;
}
void RunSingleLoop()
{
ADODB::_ConnectionPtr conn = NULL;
// Open local conn for loop.
conn = GetJetConnection();
Reset(conn);
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;
cmd->CommandText = L"qdMissingData";
cmd->CommandType = ADODB::adCmdStoredProc;
v1 = 1L;
cmd->Parameters->Append(cmd->CreateParameter(
L"P1",ADODB::adInteger,ADODB::adParamInput,-1, v1));
v1.Clear();
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.
cmd->CommandText = L"qiMissingRecord";
cmd->CommandType = ADODB::adCmdStoredProc;
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();
// Execute statement.
cmd->Execute(NULL,NULL,ADODB::adExecuteNoRecords);
// Cleanup
cmd->ActiveConnection = NULL;
cmd = NULL;
}
.
- References:
- ADODB Command memory leak
- From: khalprin
- Re: ADODB Command memory leak
- From: Val Mazur \(MVP\)
- Re: ADODB Command memory leak
- From: khalprin
- Re: ADODB Command memory leak
- From: Matt Neerincx [MS]
- ADODB Command memory leak
- Prev by Date: Filter and two wildcars error
- Next by Date: Re: Filter and two wildcars error
- Previous by thread: Re: ADODB Command memory leak
- Next by thread: Suppressing TSQL print messages from SQL batches
- Index(es):