Notice: This website is an unofficial Microsoft Knowledge Base (hereinafter KB) archive and is intended to provide a reliable access to deleted content from Microsoft KB. All KB articles are owned by Microsoft Corporation. Read full disclaimer for more details.

PRB: ADO Disconnected Recordset Appears to Leak Memory when Editing in Place


View products that this article applies to.

This article was previously published under Q269842

↑ Back to the top


Symptoms

When you attempt to update the same field repeatedly in an ActiveX Data Objects (ADO) disconnected Recordset, you may see memory increase as if there was a memory leak. This behavior only occurs with certain data types. Please see the "More Information" section of this article for a list of affected data types.

↑ Back to the top


Cause

The ADO disconnected Recordset uses a memory-mapped file for storage. When you modify a field of certain types that are affected by this behavior, a new buffer is created at the end of the rowset and the new value is added there. Repeatedly modifying an existing record results in memory increasing continuously as the memory-mapped file gets larger and larger. The update algorithm does not recognize that it is just an in-place update.

Although this behavior appears to be a memory leak, it is not truly a leak because the memory gets reclaimed when the Recordset is released.

↑ Back to the top


Status

This behavior is by design.

↑ Back to the top


More information

Steps to Reproduce Behavior

  1. Create an empty console application project in Microsoft Visual C++.
  2. Insert the following sample code that updates one field of the same record repeatedly:
    
    #undef EOF
    #import "C:\Program Files\Common Files\System\Ado\msado15.dll" no_namespace
    
    void main(void)
    {
    	_RecordsetPtr rs;
    	HRESULT hr = CoInitialize(NULL);
    
    	try 
    	{
    		hr = rs.CreateInstance(__uuidof(Recordset));
    		rs->CursorLocation = adUseClient;
    		rs->Fields->Append("BSTRString",adBSTR,10,adFldUpdatable);
    		hr = rs->Open(vtMissing,vtMissing,adOpenStatic,adLockOptimistic,-1);
    		hr = rs->AddNew();
    		rs->Fields->GetItem("BSTRString")->Value = OLESTR("");
    		//make the leak here
    		//update the first record repeatedly
    		_bstr_t bstrTest("Text to update field to.");
    		rs->MoveFirst();
    		for (int i = 0; i < 100000; i++)
    		{
    			rs->Fields->GetItem("BSTRString")->Value = bstrTest;
    			rs->Update();
    		}
    		rs->Close();
    	}
    	catch(_com_error& e) {
    		_bstr_t bstrErrorMessage(e.ErrorMessage());
    		_bstr_t bstrDescription(e.Description());
    	} 
    
    }
    
    					
  3. Compile and run the application.
  4. Watch this process with PerfMon, and you will notice a steady increase in the Private Bytes counter for the process, similar to what happens with a memory leak.

Affected Data Types

The following types of fields all are subject to this behavior:

Collapse this tableExpand this table
TypeSize
adBSTRany
adChar>255
adVarChar>255
adLongVarCharany
adWChar >127
adVarWChar>127
adLongVarWCharany


To prevent the memory increase, use the preceding chart to choose a data type that is not affected by this behavior. For example, an adChar of size 255 or smaller. Closing the recordset frees the memory as well.

↑ Back to the top


Keywords: KB269842, kbprb, kbfix, kbcodesnippet

↑ Back to the top

Article Info
Article ID : 269842
Revision : 3
Created on : 5/12/2003
Published on : 5/12/2003
Exists online : False
Views : 439