2010-09-28 20 views
7

Ho un problema strano con la mia applicazione, l'utilizzo della memoria sale di qualche centinaio di megabyte in una volta ogni tanto e alla fine l'applicazione si blocca. L'applicazione è scritta con Delphi, utilizza database, COM (per OPC) e TCP/IP.Perdita di memoria con Delphi/DBExpress

Con FastMM ho seguito lo screenshot dell'utilizzo della memoria. Non sono completamente sicuro di come leggere la tabella, ma sembra che qualcosa abbia assegnato 296463552 byte (0x100fb000, è quel "numero magico"?) Tre volte.

memory usage

Tutte le idee? C'è un modo per tenere traccia delle allocazioni di memoria non Delphi-MM?

Utilizzo Delphi 2007 con FastMM 4.96.

Edit:

Ho scritto una piccola classe di supporto utilizzando IMallocSpy per monitorare le allocazioni di memoria COM. Ecco un estratto da quello che ho ottenuto:

00119023 5:52:27.484 [4496] TCOMAllocSpy.PreRealloc size: 269462304 
00119024 5:52:27.734 [4496] (0002760C){ntdll.dll } [7C82860C] KiFastSystemCallRet + $0 
00119025 5:52:27.734 [4496] (0009F83A){MyApp.exe} [004A083A] JclDebug.JclCreateThreadStackTrace (Line 3943, "JclDebug.pas" + 7) + $1E 
00119026 5:52:27.734 [4496] (003D496A){MyApp.exe} [007D596A] ComLeakHelper.TCOMAllocSpy.DebugStack (Line 46, "ComLeakHelper.pas" + 2) + $9 
00119027 5:52:27.734 [4496] (003D4B52){MyApp.exe} [007D5B52] ComLeakHelper.TCOMAllocSpy.PreRealloc (Line 125, "ComLeakHelper.pas" + 4) + $2 
00119028 5:52:27.734 [4496] (000053B6){MyApp.exe} [004063B6] [email protected] (Line 14090, "sys\system.pas" + 10) + $0 
00119029 5:52:27.734 [4496] (002E4490){MyApp.exe} [006E5490] DBXCommon.TDBXCommand.SetText (Line 5304, "..\..\..\..\..\src\pas\dbx\driver\DBXCommon.pas" + 13) + $5 
00119030 5:52:27.734 [4496] (0010A340){MyApp.exe} [0050B340] WideStrings.TWideStrings.GetValue (Line 580, "common\WideStrings.pas" + 3) + $D 
00119031 5:52:27.734 [4496] (002E1AFC){MyApp.exe} [006E2AFC] DBXCommon.TDBXProperties.GetValue (Line 4046, "..\..\..\..\..\src\pas\dbx\driver\DBXCommon.pas" + 1) + $7 
00119032 5:52:27.734 [4496] (002E3FC9){MyApp.exe} [006E4FC9] DBXCommon.TDBXConnectionEx.GetProductName (Line 5071, "..\..\..\..\..\src\pas\dbx\driver\DBXCommon.pas" + 1) + $E 
00119033 5:52:27.734 [4496] (003765FA){MyApp.exe} [007775FA] SqlExpr.TSQLConnection.DoConnect (Line 2467, "..\..\..\..\..\src\pas\dbx\vcl\SqlExpr.pas" + 66) + $21 
00119034 5:52:27.734 [4496] (0011876D){MyApp.exe} [0051976D] DB.TCustomConnection.SetConnected (Line 2628, "DB.pas" + 8) + $4 
00119035 5:52:27.734 [4496] (00118728){MyApp.exe} [00519728] DB.TCustomConnection.Open (Line 2611, "DB.pas" + 0) + $4 
00119036 5:52:27.734 [4496] (00375D6F){MyApp.exe} [00776D6F] SqlExpr.TSQLConnection.CheckConnection (Line 2302, "..\..\..\..\..\src\pas\dbx\vcl\SqlExpr.pas" + 4) + $2 
00119037 5:52:27.734 [4496] (00379241){MyApp.exe} [0077A241] SqlExpr.TCustomSQLDataSet.CheckConnection (Line 3955, "..\..\..\..\..\src\pas\dbx\vcl\SqlExpr.pas" + 2) + $2 
00119038 5:52:27.734 [4496] (0037968A){MyApp.exe} [0077A68A] SqlExpr.TCustomSQLDataSet.OpenCursor (Line 4045, "..\..\..\..\..\src\pas\dbx\vcl\SqlExpr.pas" + 3) + $4 
00119039 5:52:27.734 [4496] (00125EA9){MyApp.exe} [00526EA9] DB.TDataSet.SetActive (Line 9245, "DB.pas" + 12) + $7 
00119040 5:52:27.734 [4496] (00125CA1){MyApp.exe} [00526CA1] DB.TDataSet.Open (Line 9201, "DB.pas" + 1) + $6 
... 

Quindi, il problema sembra essere nella connessione di database. Sto usando Firebird 2.1, DBExpress e InterXpress per i driver Firebird di Upscene.

Edit2: Questo sembra di analizzare problema simile, almeno il focus è sulla stessa linea come qui: http://www.yac.com.pl/mt.texts.sqlexpr-2.en.html

+0

Si può provare se VMMap da sysinternals ti dà più informazioni, ma un modo sicuro per rintracciare questo sarebbe usare procdump (da sysinternals). È possibile creare automaticamente un file di dump quando viene superato un limite di memoria e analizzare il dump con WinDbg. –

+0

VMMap ha dato sostanzialmente le stesse informazioni, c'è uno (o più) grande blocco allocato. Non aiuta a scoprire la fonte della perdita – Harriv

+0

FastMM 4.90 ha una funzione 'AllocateLargeBlock'. Proverei a posizionare qui un punto di interruzione condizionale su una dimensione abbastanza grande. –

risposta

0

Prova EurekaLog di individuare il problema.

+0

Vedere il mio commento ad André, lo stesso vale per EurekaLog così come per il rilevamento di perdite integrato di FastMM, poiché l'allocazione di memoria non viene eseguita tramite Delphi memory manager (= FastMM). – Harriv

+0

E sì, sto utilizzando EurekaLog :) – Harriv