Memory leak with ADO

From: Wayne (mewayne_at_hotmail.com)
Date: 01/20/04


Date: 20 Jan 2004 10:16:13 -0800

I have an app (code follows) in D7, running on Win2k sp4, with Mdac
2.8, and MSql Client utils installed, with SP3. I am simply setting a
TADOQuery.SQL.Text to a select statement, then calling open followed
by Close. When the app runs through the loop 2k times about 16-30 megs
of ram gets allocated. I've been able to duplicate this on many 2k
machines, but have sent the app to others and others don't have the
issue. I've tried it on XP and no issue.

Any Ideas?

Thanks
Wayne

The test application expects to be pointed to Microsoft SQL Northwind
database. the Order Details should have over 2k rows in it.

Most will know what to do with this, but for those who don't:

Open Delphi
Create a new application
Copy and paste the source in the forms source overwriting what is
there.
View the form
hit Alt+F12
copy and paste the form code over the code that is there.
hit Alt+F12
Run the app.

______________________________SOURCE
CODE_________________________________
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms,
  INIFiles, Dialogs, StdCtrls, Buttons, DB, ADODB;

type
  TForm1 = class(TForm)
    ConnectionEdit: TEdit;
    Label1: TLabel;
    SpeedButton1: TSpeedButton;
    Button1: TButton;
    Connection: TADOConnection;
    ADOQuery1: TADOQuery;
    procedure SpeedButton1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses
  AdoConEd;

{$R *.dfm}

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
  Connection.Close;
  Connection.ConnectionString := ConnectionEdit.Text;
  if EditConnectionString(Connection) then
    ConnectionEdit.Text := Connection.ConnectionString;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  with TIniFile.Create(ChangeFileExt(Application.ExeName, '.ini')) do
    try
      ConnectionEdit.Text := ReadString('Database',
'ConnectionString', '');
    finally
      Free;
    end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  with TIniFile.Create(ChangeFileExt(Application.ExeName, '.ini')) do
    try
      WriteString('Database', 'ConnectionString',
ConnectionEdit.Text);
    finally
      Free;
    end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  StringList: TStringList;
  Query: TADOQuery;
  i: Integer;
begin
  if Connection.ConnectionString = '' then
    Connection.ConnectionString := ConnectionEdit.Text;
  StringList := TStringList.Create;
  try
    ADOQuery1.Open;
    try
      while not ADOQuery1.Eof do
      begin
        StringList.Add(ADOQuery1.Fields[0].AsString);
        ADOQuery1.Next;
      end;
    finally
      ADOQuery1.Close;
    end;

    ShowMessage('Check total allocated memory, watch it go up after
you hit OK');
    for i := 0 to StringList.Count - 1 do
    begin
      Query := TADOQuery.Create(Self);
      try
        //Query.Connection := Connection;
        Query.ConnectionString := ConnectionEdit.Text;
        Query.SQL.Text := Format('Select Count(*) from "ORDER DETAILS"
where OrderID = %s',
          [StringList[i]]);
        Query.Open;
        Query.Close;
      finally
        Query.Free;
      end;
    end;
  finally
    StringList.Free;
  end;
end;

end.
______________________________END SOURCE
CODE_________________________________

______________________________FORM
CODE_________________________________
object Form1: TForm1
  Left = 192
  Top = 108
  Width = 246
  Height = 115
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  OnClose = FormClose
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 8
    Top = 8
    Width = 84
    Height = 13
    Caption = 'Connection String'
  end
  object SpeedButton1: TSpeedButton
    Left = 208
    Top = 24
    Width = 23
    Height = 22
    Caption = '...'
    OnClick = SpeedButton1Click
  end
  object ConnectionEdit: TEdit
    Left = 8
    Top = 24
    Width = 193
    Height = 21
    ReadOnly = True
    TabOrder = 0
  end
  object Button1: TButton
    Left = 160
    Top = 56
    Width = 75
    Height = 25
    Caption = 'Go'
    TabOrder = 1
    OnClick = Button1Click
  end
  object Connection: TADOConnection
    LoginPrompt = False
    Left = 8
    Top = 56
  end
  object ADOQuery1: TADOQuery
    Connection = Connection
    Parameters = <>
    SQL.Strings = (
      'Select'
      ' *'
      'From'
      ' "ORDER DETAILS"')
    Left = 40
    Top = 56
  end
end
______________________________END FORM
CODE_________________________________