我有一个在 Delphi /VCL下稳定的小程序。我重新创建了一个FireMonkey应用程序,虽然它运行,但使用的内存不断增加,直到应用程序变得没有React和崩溃。
我有一个Indy TIdUDPServer
接收SysLog消息。使用OnUDPRead
事件处理程序,我将AData
复制到String
,并调用另一个过程,该过程解析字符串并将结果输出到TListBox
(并发送到数据库,尽管为了清楚起见,我删除了该函数)。
我认为问题可能是由于从事件处理程序调用String
处理例程,该事件处理程序在工作线程中运行,然后将项目添加到TListBox
。
作为一个测试,我尝试通过在事件处理程序中设置一个全局“flag”为true,并使用一个计时器来将事件处理程序从后续操作中分离出来,查找该标志,如果设置了该标志,则调用处理例程,这样Indy事件处理程序就不会访问任何UI组件。但是,内存仍然会增长。
为什么这个程序在作为VCL项目运行时可以正常工作,而在FMX中却不行?
如何避免FMX?中的内存增长问题?
procedure TForm1.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread;
const AData: TIdBytes; ABinding: TIdSocketHandle);
begin
IP := ABinding.PeerIP; // global string
SysMsg := BytesToString(AData);// global string
DataAvailable := True; // global semaphore variable
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if DataAvailable then
begin
DataAvailable := False;
ProcessMessage(IP, SysMsg);
end;
end;
procedure TForm1.ProcessMessage(IP, SysLogMsg: String);
begin
// Dissect Syslog string
// Add Items to listbox
// Post items to Database using FDCOnnection, FDQuery (problem remains with this removed)
end;
1条答案
按热度按时间d7v8vwbk1#
雷米,谢谢你的回复。按照你的建议,我把ProcessMessage过程精简到只剩下几行代码,但仍然有内存增长的问题。下面是我能给予的最小的例子,简单地使用一个计时器把字符串注入一个列表框。
最后一行设置ListBox1.ItemIndex导致了这个问题。如果我将其注解掉并重新编译,内存问题就会消失。如果我将其重建为VCL项目,该示例运行时不会出现内存问题。
我使用的是 Delphi 10.4,我在Windows 10 Pro和Windows Server 2012上运行代码,结果相同。
我注意到FMX版本使用的内存大约是VCL版本的10倍(运行时没有出错的行),这是预期的吗?
我确实尝试过使用TIDSysLogServer,但在尝试解释来自Cisco阿萨防火墙的系统日志消息时,它会引发运行时错误。
Cisco系统日志消息中的时间戳如下所示:2022年10月16日19时03分27秒+01时00分:
非常感谢