데이터베이스 연결을 위해 ADO를 사용하는 응용 프로그램, 주로 TAdoConnection 및 TAdoQuery를 디버깅합니다. 일부 테스트 후에 TAdoQuery가 메모리를 소비하지 않고 계속 사용하고 있음이 밝혀졌습니다. 문제는이 코드를 아주 쉽게 재현 할 수 있습니다 :델파이 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'을 사용하여 메모리를 소비하며 속도는 느려집니다. '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과 비슷합니다.
이것이 델파이의 버그라고 생각합니까? 해결 방법이 있습니까?
업데이트 : 이 개체는 정적 인 경우에도 실제로 표시됩니다. 예 : 연결 및 쿼리 구성 요소는 양식에 배치되며 연결은 열린 상태로 유지됩니다. 쿼리 SQL 텍스트 만 변경되고 실행됩니다.
PGfoundry.org에서 다른 제공 업체를 설치하려했지만 결과가 이상합니다.
메모리 누수는 다른 운영체제에서는 Postgres 제공자와 함께 있지만 MySQL에서는 나타나지 않습니다. 그게 무슨 뜻인지는 모르겠다. VCL 문제라면 항상 존재하지 않아야합니까? 그렇지 않은 경우 동일한 DB 서버에 대해 다른 공급자가 발생하는 것을 고려할 때 어떤 계층이 원인입니까?
시스템의 MDAC를 최신 릴리스로 업데이트 했습니까? OleDB 레이어에 직접 액세스 했습니까? [우리의 오픈 소스 장치] (http://blog.synopse.info/post/2011/06/27/SynOleDB%3A-OpenSource-Unit-for-direct- OleDB를 통한 데이터베이스 액세스). –
QC 주석은 클라이언트 측 대신 서버 측 커서를 사용하려고하는 것이 좋습니다. 이걸 시험해 봤어? – whosrdaddy
불행히도 MDAC를 업데이트하고 Server 2008과 2003 모두에서 동일한 결과를 테스트했습니다. 커서는 메모리 소비에도 영향을 미치지 않습니다. 직접 액세스에 관해서는, 코드의 너무 많은 부분을 다시 작성하는 것을 피하기 위해 아직 시도하지 않았습니다.이 코드는 꽤 크고 나에 의해 작성되지 않았습니다. 다른 옵션이없는 경우에도 시도해 보겠습니다. – VGeorgiev