2010-09-28 15 views
7

J'ai un problème étrange avec mon application, son utilisation de la mémoire monte jusqu'à quelques centaines de mégaoctets à la fois de temps en temps et finalement l'application se fige. L'application est écrite avec Delphi, elle utilise la base de données, COM (pour OPC) et TCP/IP.Fuite de mémoire avec Delphi/DBExpress

Avec FastMM j'ai suivi la capture d'écran de l'utilisation de la mémoire. Je ne suis pas complètement sûr comment lire cette table, mais il semble que quelque chose a alloué 296463552 octets (0x100fb000, est ce "nombre magique"?) Trois fois.

memory usage

Toutes les idées? Existe-t-il un moyen de suivre les allocations de mémoire non-Delphi-MM? Je utilise Delphi 2007 avec FastMM 4.96.

Edit:

j'ai écrit une petite classe d'aide en utilisant IMallocSpy pour suivre les allocations de mémoire COM. Voici un extrait de ce que j'ai:

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 
... 

Donc, le problème semble être dans la connexion à la base de données. J'utilise les pilotes Firebird 2.1, DBExpress et InterXpress for Firebird d'Upscene.

Edit2: Cela semble analyser le même problème, au moins l'accent est mis sur les mêmes lignes comme ici: http://www.yac.com.pl/mt.texts.sqlexpr-2.en.html

+0

Vous pouvez essayer si VMMap de sysinternals vous donne plus d'informations mais un moyen sûr de suivre ce serait d'utiliser procdump (à partir de sysinternals). Avoir automatiquement créer un fichier de vidage quand une limite de mémoire est dépassée et analyser l'image avec WinDbg. –

+0

VMMap donne essentiellement les mêmes informations, il y a un (ou plus) gros bloc alloué. Il n'aide pas à trouver la source de la fuite – Harriv

+0

FastMM 4.90 a une fonction 'AllocateLargeBlock'. J'essaierais de placer un breakpoint conditionnel ici sur une taille assez grande. –

Répondre

1

Quand est gelé votre application, votre peut essayer de regarder la pile de découvrir pourquoi il est gelé: http://code.google.com/p/asmprofiler/wiki/ProcessStackViewer

Vous pouvez memproof essayer de retracer toute l'allocation des ressources (et leur stacktrace): http://www.torry.net/tools/debug/memory/memp0948.zip

+0

J'ai essayé de créer des allocations de mémoire similaires avec CoTaskMemAlloc (qui a fonctionné), mais memproof ne peut pas les suivre. – Harriv

0

Essayez EurekaLog localiser le problème.

+0

Voir mon commentaire sur André, il en va de même pour EurekaLog ainsi que pour la détection de fuites intégrée FastMM, puisque l'allocation mémoire n'est pas effectuée par le gestionnaire de mémoire Delphi (= FastMM). – Harriv

+0

Et oui, je cours EurekaLog :) – Harriv