2012-06-12 3 views
1

데이터베이스 연결을 위해 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 서버에 대해 다른 공급자가 발생하는 것을 고려할 때 어떤 계층이 원인입니까?

+0

시스템의 MDAC를 최신 릴리스로 업데이트 했습니까? OleDB 레이어에 직접 액세스 했습니까? [우리의 오픈 소스 장치] (http://blog.synopse.info/post/2011/06/27/SynOleDB%3A-OpenSource-Unit-for-direct- OleDB를 통한 데이터베이스 액세스). –

+0

QC 주석은 클라이언트 측 대신 서버 측 커서를 사용하려고하는 것이 좋습니다. 이걸 시험해 봤어? – whosrdaddy

+0

불행히도 MDAC를 업데이트하고 Server 2008과 2003 모두에서 동일한 결과를 테스트했습니다. 커서는 메모리 소비에도 영향을 미치지 않습니다. 직접 액세스에 관해서는, 코드의 너무 많은 부분을 다시 작성하는 것을 피하기 위해 아직 시도하지 않았습니다.이 코드는 꽤 크고 나에 의해 작성되지 않았습니다. 다른 옵션이없는 경우에도 시도해 보겠습니다. – VGeorgiev

답변

1

귀하의 사례에 해당되는지는 모르지만 과거에는 SQL Server에 연결된 Windows Server 2008 (Win7에도 적용 가능)과 비슷한 메모리 문제가있었습니다.

이 2 원인이었다 :

  1. 를 ConnectionString이 Persist Security Info=true

  2. 변화를 ("설계된대로 -"동작을) 포함되지 않은 누수의 원인이 된 MDAC 스택

    석사 버그에서 디버그 정보를 무료로 제공하지 않는 MS의 Critical Section implementation.

가능한 해결 방법은 연결을 항상 닫은 후 다시 열지 말고 실용적으로 유지하는 것입니다.

+0

제안 해 주셔서 감사합니다. Persist Security Info는 불행하게도 동작을 변경하지 않습니다. 최신 테스트를 반영하기 위해 위 질문을 업데이트했습니다. 문제는 연결 유지 여부에 영향을받지 않으므로 쿼리 자체와 관련된 것으로 보입니다. – VGeorgiev

0

DB2에 연결하는 동안 동일한 문제가있어서 MS/SQL에 국한되지 않습니다. 엠바 카데로 포럼에서 진행되는 스레드가 있었지만 종료되었습니다. 이 사람들에게 내 코드가 아닌 다른 것을 설득 할 수있는 방법이 없었습니다. 심지어 내가 barest 꼭대기에서 그것을 벗겨 냈을 때, 나는 그 문제와는 전혀 관련이없는 추천을 되찾았다. 내 프로세스가 7/24/365 다중 스레드 프로그램이기 때문에 마침내 스케줄러에서 실행하고 매일 종료하는 방식으로 사임했습니다. 추악한 수정이지만 내 고객에게 청구 할 수 있어야합니다!

나는 또한 C#에서 동일한 문제를 만들 수 있는지 확인하기 위해 약간의 테스트 응용 프로그램을 작성했습니다. 나는 거기에서 성장하는 기억의 발자국을 보지 못했다. 이것은 델파이 문제입니다.