I am debugging an application that uses ADO for database connectivity, mostly TAdoConnection and TAdoQuery After some testing it turned out that the TAdoQuery keeps consuming and not releasing memory. The problem can be reproduced quite easily with this code:
procedure TForm1.RunQueries;
var
Q: TADOQuery;
Conn: TADOConnection;
begin
Conn := TADOConnection.Create(nil);
Conn.ConnectionString := 'Provider=PGNP.1;Password=*****;User ID=*****;Data Source=*****;Initial Catalog=*****;Extended Properties="PORT=5432"';
Conn.LoginPrompt:=False;
Conn.Connected := true;
Q := TADOQuery.Create(nil);
Q.Connection := Conn;
Q.SQL.Text := 'select * from sometable where extract(year from now()-Field1)::int/60>=15 or Field2>=50 limit 5';
q.Open;
q.Close;
FreeAndNil(Q);
FreeAndNil(Conn);
end;
If this is run with a timer at some interval (e.g. 200ms) the memory consumed keeps rising with various speeds (20-50MB per hour). The SQL text itself is not really relevant. It also consumes memory with 'select * from Table1', only slower. ExecSQL with a 'delete ...' statement does not seem to cause a problem.
I did some tests with GetProcessMemoryInfo and it seems that the memory is consumed and not released after the Open method is called. Not all executions resulted in the same memory increase though.
This happens at the development server with PostgreSQL and different ADO providers, but I could not reproduce it with MySQL. Other apps using the ADO provider from http://www.pgoledb.com seem to be working properly, so the problem is not only in the provider I tried AQTime and FastMM4, but both report no leaks. The code built with D6 and XE2 works the same.
I found this question Delphi: TAdoQuery Memory Leak?, but the problem there was caused by errors in the code.
My problem is similar to this error report http://qc.embarcadero.com/wc/qcmain.aspx?d=7018.
Do you think this is a bug in Delphi and is there a workaround?
An update: This problem actually appears even if the objects are static. E.g a Connection and Query components which are put on the form, and the connection is kept open. Only the Query SQL text is changed and executed.
I tried to install a different provider from PGfoundry.org, but the results are strange for me.
The memory leaks appear with both Postgres providers on different OSs, but not with MySQL. I am not sure what that means though. If it is a VCL problem, shouldn't it be always present? If not, what layer is causing it considering that it happens with different providers for the same DB server?