我正在调试一个使用 ADO 进行数据库连接的应用程序,主要是 TAdoConnection 和 TAdoQuery 经过一些测试后发现 TAdoQuery 一直在消耗内存而不是释放内存。使用以下代码可以很容易地重现该问题:
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;
如果以某个时间间隔(例如 200 毫秒)使用计时器运行,则消耗的内存会以各种速度(每小时 20-50MB)不断增加。SQL 文本本身并不真正相关。它还使用“select * from Table1”消耗内存,只是速度较慢。带有 'delete ...' 语句的 ExecSQL 似乎不会引起问题。
我用 GetProcessMemoryInfo 做了一些测试,似乎在调用 Open 方法后内存被消耗而不是释放。不过,并非所有执行都会导致相同的内存增加。
这发生在使用 PostgreSQL 和不同 ADO 提供程序的开发服务器上,但我无法使用 MySQL 重现它。其他使用来自http://www.pgoledb.com的 ADO 提供程序的应用程序似乎工作正常,所以问题不仅在于我尝试过 AQTime 和 FastMM4 的提供程序,而且都报告没有泄漏。使用 D6 和 XE2 构建的代码工作方式相同。
我发现这个问题Delphi: TAdoQuery Memory Leak? ,但是那里的问题是由代码中的错误引起的。
我的问题类似于此错误报告http://qc.embarcadero.com/wc/qcmain.aspx?d=7018。
您认为这是 Delphi 中的一个错误,是否有解决方法?
更新: 即使对象是静态的,也会出现此问题。例如,放置在表单上的 Connection 和 Query 组件,并且连接保持打开状态。只有查询 SQL 文本被更改和执行。
我尝试从 PGfoundry.org 安装不同的提供程序,但结果对我来说很奇怪。
内存泄漏出现在不同操作系统上的两个 Postgres 提供程序中,但没有出现在 MySQL 中。我不确定这意味着什么。如果是 VCL 问题,不应该一直存在吗?如果不是,考虑到同一数据库服务器的不同提供商会发生这种情况,是什么层导致它?