S
Sander Verhagen
Hi,
Using ADO I'm experiencing what I would call a memory leak. It might
formally not be one, because I have no prove that my application is not
nicely releasing the data on exit, but every time the code below is called,
the memory use of my application (as Windows Task Manager shows it) is
increased. As far as I can see, the amount of memory use increase depends on
the size of the retrieved record set.
I've included my Open function implementation from which the ADO connection
is opened (just once). Also I've included one of my LoadRecords functions
where it seems to go wrong. Stepping into my code seems to show that the
memory is increased when I call Execute, thus when a record set is opened,
which isn't strange, but it should be released once I leave the function,
shouldn't it? Do I close up my record sets incorrectly after use, or what's
wrong here?
// typical connection string:
// Provider=sqloledb;Data Source=...;Initial Catalog=...;User
Id=sa;Password=...
// yes, it's a MS SQL Server
SCCS Open(LPCSTR connectionstring)
{
::CoInitialize(NULL);
try
{
// Create an "empty" connection
m_hresult = m_pConnection.CreateInstance(__uuidof(Connection));
if( SUCCEEDED(m_hresult) )
{
// Open a designated connection
m_hresult = m_pConnection->Open(connectionstring, "", "",
adConnectUnspecified);
if( SUCCEEDED(m_hresult) )
{
m_pConnection->CursorLocation = adUseClient;
return SUCCESS;
}
}
}
catch(_com_error &e)
{
m_hresult = -1;
DoError(e);
}
return FAIL;
}
SCCS LoadRecords( ... )
{
if( IsOpen() )
{
// Format a SQL string to query the records with
CString sql;
/* here goes the code to set up the SQL string */
ThreadLock();
try
{
// Open a recordset with the made up SQL string
COleVariant RecordsAffected;
_RecordsetPtr set;
set = m_pConnection->Execute( sql.AllocSysString(),
RecordsAffected, adCmdText );
// Check if anything in recordset
if( !(set->EndOfFile && set->BOF) )
{
// Get to first record
set->MoveFirst();
while( !set->EndOfFile )
{
/* put the retrieved records into memory objects, here */
/* I'm pretty darn quite sure that this isn't where the
problem is */
}
}
set->Close();
set = 0;
ThreadUnlock();
return SUCCESS;
}
catch(_com_error &e)
{
DoError(e);
}
ThreadUnlock();
}
return FAIL;
}
#define SCCS BOOL
#define SUCCESS FALSE
#define FAIL TRUE
This code isn't ready to compile for you, guys, but it is semantically
exactly what I am doing.
Where is my memory going??? *cry* My application is one that has to run for
days... well, actually "forever", but I'd settle for "for days" now. What
happens now is that it'll be using soooo much memory after a day that
restarting the application is just plain wise. (That really solves the
problem, so it looks that at that time all this memory is actually
released.)
I would be sooo grateful for you helping me out on this, as this has been
driving me up the walls for days now!!!
All the best,
Sander Verhagen
[ (e-mail address removed) ]
Using ADO I'm experiencing what I would call a memory leak. It might
formally not be one, because I have no prove that my application is not
nicely releasing the data on exit, but every time the code below is called,
the memory use of my application (as Windows Task Manager shows it) is
increased. As far as I can see, the amount of memory use increase depends on
the size of the retrieved record set.
I've included my Open function implementation from which the ADO connection
is opened (just once). Also I've included one of my LoadRecords functions
where it seems to go wrong. Stepping into my code seems to show that the
memory is increased when I call Execute, thus when a record set is opened,
which isn't strange, but it should be released once I leave the function,
shouldn't it? Do I close up my record sets incorrectly after use, or what's
wrong here?
// typical connection string:
// Provider=sqloledb;Data Source=...;Initial Catalog=...;User
Id=sa;Password=...
// yes, it's a MS SQL Server
SCCS Open(LPCSTR connectionstring)
{
::CoInitialize(NULL);
try
{
// Create an "empty" connection
m_hresult = m_pConnection.CreateInstance(__uuidof(Connection));
if( SUCCEEDED(m_hresult) )
{
// Open a designated connection
m_hresult = m_pConnection->Open(connectionstring, "", "",
adConnectUnspecified);
if( SUCCEEDED(m_hresult) )
{
m_pConnection->CursorLocation = adUseClient;
return SUCCESS;
}
}
}
catch(_com_error &e)
{
m_hresult = -1;
DoError(e);
}
return FAIL;
}
SCCS LoadRecords( ... )
{
if( IsOpen() )
{
// Format a SQL string to query the records with
CString sql;
/* here goes the code to set up the SQL string */
ThreadLock();
try
{
// Open a recordset with the made up SQL string
COleVariant RecordsAffected;
_RecordsetPtr set;
set = m_pConnection->Execute( sql.AllocSysString(),
RecordsAffected, adCmdText );
// Check if anything in recordset
if( !(set->EndOfFile && set->BOF) )
{
// Get to first record
set->MoveFirst();
while( !set->EndOfFile )
{
/* put the retrieved records into memory objects, here */
/* I'm pretty darn quite sure that this isn't where the
problem is */
}
}
set->Close();
set = 0;
ThreadUnlock();
return SUCCESS;
}
catch(_com_error &e)
{
DoError(e);
}
ThreadUnlock();
}
return FAIL;
}
#define SCCS BOOL
#define SUCCESS FALSE
#define FAIL TRUE
This code isn't ready to compile for you, guys, but it is semantically
exactly what I am doing.
Where is my memory going??? *cry* My application is one that has to run for
days... well, actually "forever", but I'd settle for "for days" now. What
happens now is that it'll be using soooo much memory after a day that
restarting the application is just plain wise. (That really solves the
problem, so it looks that at that time all this memory is actually
released.)
I would be sooo grateful for you helping me out on this, as this has been
driving me up the walls for days now!!!
All the best,
Sander Verhagen
[ (e-mail address removed) ]