Microsoft KB Archive/294168

= BUG: Memory Leak in OLE DB Provider for SQL Server When It Is Loaded and Unloaded Multiple Times =

Article ID: 294168

Article Last Modified on 4/6/2004

-

APPLIES TO


 * Microsoft Data Access Components 2.5
 * Microsoft Data Access Components 2.6

-



This article was previously published under Q294168



SYMPTOMS
You may see a memory leak when repeatedly loading and unloading the Microsoft OLE DB provider for SQL Server (SQLOLEDB) and connecting to a Microsoft SQL Server database. You may see the same behavior when using the Microsoft OLE DB provider for ODBC drivers (MSDASQL) with the SQL Server ODBC driver.



CAUSE
This is caused by a slight memory leak in the OLE DB implementation support routines (Msdatl2.dll or Msdatl3.dll).



RESOLUTION
To work around this problem, keep a global connection alive or have the COM library initialized in the main thread.



STATUS
Microsoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article. This problem was corrected in MDAC 2.7, and MDAC 2.5 Service Pack 3 (SP3).

There is also a hotfix available for this problem. For additional information about this hotfix, click the article number below to view the article in the Microsoft Knowledge Base:

312575 FIX: Virtual Memory Leak with Large Number of Concurrently Open Recordsets



Steps to Reproduce the Behavior
  Create a Win32 console application in Microsoft Visual C++ 6.0 using the following code:
 * 1) include 
 * 2) include 


 * 1) import  no_namespace rename(&quot;EOF&quot;, &quot;EndOfFile&quot;)

void TestFunction {      // Initialize COM library. CoInitialize(NULL);

try {          _ConnectionPtr pConn(__uuidof(Connection)); _CommandPtr pCmd(__uuidof(Command)); _RecordsetPtr pRs;

// Open the database connection. _bstr_t strCnn(&quot;Provider=SQLOLEDB;Data Source= ;Initial Catalog=pubs;User ID= ;Password= ;&quot;); pConn->Open(strCnn, &quot;&quot;, &quot;&quot;, -1);

// Set command object's properties. pCmd->ActiveConnection = pConn; pCmd->CommandText = &quot;select * from authors&quot;; pCmd->CommandType = adCmdText; // Execute the SQL statement. pRs = pCmd->Execute(NULL,NULL,adCmdText); pRs->MoveFirst;

pRs->Close; pConn->Close; }   catch (_com_error &e) {      _tprintf(&quot;Error\n&quot;); _tprintf(&quot;\tCode = %08lx\n&quot;, _T(e.Error)); _tprintf(&quot;\tCode meaning = %s\n&quot;, _T(e.ErrorMessage)); _tprintf(&quot;\tSource = %s\n&quot;, _T((LPCSTR) e.Source)); _tprintf(&quot;\tDescription = %s\n&quot;, _T((LPCSTR) e.Description)); }   // Uninitialise COM library. CoUninitialize; }

int main {  //CoInitialize(NULL);

// Loop for testing. for (int i = 0; i < 1000; i++) {   TestFunction; _tprintf(&quot;%d &quot;, i); Sleep(100); // Pause for some time. };

//CoUninitialize; return 0; }                    Modify the connection string to suit your environment. Run the application, and use Performance Monitor to watch the private bytes of the process. You will see the memory leak. Uncomment the initialization calls in the main function and the leak will disappear.</ol>

Additional query words: Memory Leak SQLOLEDB MSDASQL

Keywords: kbbug kbfix KB294168

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.