Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用Delphi/DBExpress实现内存泄漏_Delphi_Debugging_Memory Management_Memory Leaks_Dbexpress - Fatal编程技术网

用Delphi/DBExpress实现内存泄漏

用Delphi/DBExpress实现内存泄漏,delphi,debugging,memory-management,memory-leaks,dbexpress,Delphi,Debugging,Memory Management,Memory Leaks,Dbexpress,我的应用程序有一个奇怪的问题,它的内存使用量时不时地增加几百兆字节,最终应用程序冻结。该应用程序是用Delphi编写的,它使用数据库、COM(用于OPC)和TCP/IP 通过FastMM,我可以看到内存使用情况的屏幕截图。我不完全确定如何读取该表,但它似乎分配了296463552字节(0x100fb000,是“神奇数字”?)三次 有什么想法吗?有没有办法跟踪非Delphi MM内存分配 我正在使用Delphi2007和FastMM 4.96 编辑: 我使用IMallocSpy编写了一个小助手类

我的应用程序有一个奇怪的问题,它的内存使用量时不时地增加几百兆字节,最终应用程序冻结。该应用程序是用Delphi编写的,它使用数据库、COM(用于OPC)和TCP/IP

通过FastMM,我可以看到内存使用情况的屏幕截图。我不完全确定如何读取该表,但它似乎分配了296463552字节(0x100fb000,是“神奇数字”?)三次

有什么想法吗?有没有办法跟踪非Delphi MM内存分配

我正在使用Delphi2007和FastMM 4.96

编辑:

我使用IMallocSpy编写了一个小助手类来跟踪COM内存分配。以下是我得到的摘录:

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] System.@WStrAsg (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 
...
所以,问题似乎出在数据库连接上。我正在使用Firebird 2.1、DBExpress和InterXpress为来自Upsene的Firebird驱动程序提供支持

Edit2:
这似乎分析了类似的问题,至少重点与此处相同:

当您的应用程序冻结时,您可以尝试查看堆栈以发现其冻结的原因:

您可以尝试memproof跟踪所有资源分配(及其堆栈跟踪):

尝试使用EurekaLog查找问题。

问题是Delphi 2007 DbExpress中的bug,它出现在多线程环境中(毕竟它不是线程安全的)。此处的更多信息:

我曾尝试使用CoTaskMemAlloc创建类似的内存分配(有效),但memproof无法跟踪这些内存分配。如果Sysinternal中的VMMap提供了更多信息,您可以尝试,但跟踪这一情况的一个可靠方法是使用procdump(来自Sysinternal)。让它在超过内存限制时自动创建转储文件,并使用WinDbg分析转储。VMMap提供基本相同的信息,分配了一个(或多个)大块。查找leakFastMM 4.90的源代码没有帮助,因为它有一个
AllocateLargeBlock
函数。我会尝试在这里放置一个足够大的条件断点。这些块是“系统分配的”,至少可以使用ole32.dll中的CoTaskMemAlloc函数(可能还有其他函数)创建。根据我的测试,当调用CoTaskMem*函数时,FastMM被完全绕过。您从AQTime开始尝试过使用内存分析器吗?如果我没记错的话,它允许您跟踪所有内存分配(但跟踪它会使您的应用程序慢到爬行)。请参阅我对André的评论,这同样适用于EurekaLog以及FastMM内置泄漏检测,因为内存分配不是通过Delphi内存管理器(=FastMM)完成的。是的,我正在运行EurekaLog:)