If an ADO
Field object is referenced by using the
rs.Field("FieldName") syntax, the code is keeping a reference to the
ADODB.Field object itself instead of a reference to the default
value property of the object. When the Visual Basic scripting engine
concatenates the values together, the
IDispatch interface calls to ADO must be made internally to determine what the default property is.
For an
ADODB.Field object, the default property is the
value property. The
value property contains the actual field value. The Visual Basic
scripting engine passes an exception information structure to ADO as part of
the
IDispatch call so error information can be filled out by ADO and can be
returned if an error occurs.
If the ADO recordset is empty, ADO
allocates Source, HelpFile, and Description strings and then places the strings
in the exception information structure. However, when the exception information
structure is returned to the Visual Basic scripting engine indicating an ADO
error (because the recordset was empty), the Visual Basic scripting engine does
not free the strings that were returned to it by ADO. This behavior causes a
memory leak in the default process heap. This leak will include strings that
are similar to the following:
- "ADODB.Field"
- "Either BOF or EOF is True, or the current record has been
deleted. Requested operation requires a current record."
- "C:\WINNT\HELP\ADO270.CHM"
Steps to reproduce the problem
- Create a VBScript file that contains the following code:
on error resume next
Set conn = CreateObject("adodb.connection")
conn.open "provider=msdasql;driver=sql
server;server=YourServer;database=pubs;uid=YourUID;pwd=YourPassword;"
Set cmdTemp = CreateObject("ADODB.Command")
cmdTemp.CommandType = 1
Set cmdTemp.ActiveConnection = conn
cmdTemp.CommandText = "select au_id, au_lname,
au_fname from authors where 1 = 2"
For i = 0 To 50000
Set rs =CreateObject("ADODB.Recordset")
rs.Open cmdTemp, , 0, 1
' This code leaks memory.
x = rs("au_id") & rs("au_fname") & rs("au_lname")
' This code does not leak memory.
x = rs("au_id").value & rs("au_fname").value & rs("au_lname").value
rs.Close
set rs = Nothing
Next
conn.Close
- Modify the connection string appropriately for your
environment.