Я отлаживаю приложение, использующее ADO для подключения к базе данных, в основном TAdoConnection и TAdoQuery . После некоторого тестирования выяснилось, что TAdoQuery продолжает потреблять и не выпускать память. Проблема может быть воспроизведена довольно легко с этим кодом:Потребление памяти Delphi ADO
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-50 МБ в час). Сам текст SQL не имеет особого значения. Он также потребляет память с помощью «select * from Table1», только медленнее. ExecSQL с выражением «delete ...», похоже, не вызывает проблемы.
Я провел несколько тестов с помощью GetProcessMemoryInfo, и кажется, что память потребляется и не освобождается после вызова метода Open. Однако не все исполнения привели к тому же увеличению памяти.
Это происходит на сервере разработки с PostgreSQL и различными поставщиками ADO, но я не смог воспроизвести его с помощью MySQL. Другие приложения, использующие провайдера ADO от http://www.pgoledb.com, похоже, работают исправно, поэтому проблема не только в провайдере Я пробовал AQTime и FastMM4, но оба не сообщают об утечках. Код, построенный с D6 и XE2, работает одинаково.
Я нашел этот вопрос Delphi: TAdoQuery Memory Leak?, но проблема была вызвана ошибками в коде.
Моя проблема похожа на этот отчет об ошибке http://qc.embarcadero.com/wc/qcmain.aspx?d=7018.
Как вы думаете, это ошибка в Delphi, и есть ли обходной путь?
Обновление: Эта проблема возникает, даже если объекты являются статическими. Например, компоненты Connection и Query, которые помещаются в форму, и соединение остается открытым. Изменяется и выполняется только текст запроса Query.
Я попытался установить другого провайдера из PGfoundry.org, но результаты для меня странные.
Утечки памяти появляются вместе с поставщиками Postgres на разных ОС, но не с MySQL. Я не уверен, что это значит. Если это проблема VCL, разве она не всегда присутствует? Если нет, то какой слой вызывает его, учитывая, что это происходит с разными провайдерами для одного и того же сервера БД?
Вы обновили MDAC системы до последней версии? Вы пытались получить доступ непосредственно к слою OleDB - вы можете попробовать [наши модули с открытым исходным кодом] (http://blog.synopse.info/post/2011/06/27/SynOleDB%3A-OpenSource-Unit-for-direct- доступ к любой из баз-через-OleDB). –
В комментариях к QC предлагается попытаться использовать серверные курсоры вместо клиентской стороны. Вы проверили это? – whosrdaddy
Я обновил MDAC и протестировал на обоих серверах 2008 и 2003 с такими же результатами, к сожалению. Курсоры также не влияли на потребление памяти. Что касается прямого доступа, я еще не пробовал, так как хочу избежать перезаписи слишком большого количества кода, который довольно большой и не написан мной. Я попробую это также, если нет других вариантов. – VGeorgiev