我创建了一个小型多线程应用程序,我正在尝试将其转换为使用OmniThreadLibrary。我正在使用Virtualtreeview显示日志和状态/结果。 Vst Log只有两列,记录只包含两个字符串字段(非常简单,记录中没有对象)。
使用OTL附带的DEMO项目(线程池#11)我将项目更改为使用VirtualTreeview而不是列表框。当我从演示中“运行任务”时没有内存泄漏,但是如果我不止一次运行“运行任务”,就会发生内存泄漏。如果我多次运行任何任务,将发生内存泄漏。如果我根本不使用VirtualTreeView,则任何时候都不会发生内存泄漏。就在我使用VST和任务多次运行时。
我确实使用FreeNode事件并清除字符串,甚至尝试使用Finalize ...
示例:
procedure TFormMain.vstLogFreeNode(Sender: TBaseVirtualTree;
Node: PVirtualNode);
var
LogData: PTreeLogData;
begin
LogData:=Sender.GetNodeData(Node);
if Assigned(LogData) then begin
LogData^.Msgtype := '';
LogData^.Msg := '';
end;
//Finalize(LogData^);
end;
为什么在多次运行任务时会出现内存泄漏? Delphi 2010与FastMM4 最新的Virtualtreeview和OTL
答案 0 :(得分:10)
仅为验证的节点调用NodeFree事件,验证通常表示一次或多次显示的节点(调用GetText事件时)。 See Memory Leaks when using the Virtual TreeView Component
编辑:您可以通过检查节点数并计算调用NodeFree事件的次数来确认。
答案 1 :(得分:4)
我不知道为什么会发生这种情况,但我知道你怎么知道:打开FastMM的FullDebugMode。 (为此,您需要从SourceForge下载FastMM完整版。)打开在文件中提供内存泄漏报告的选项,并确保项目生成详细的映射文件。一旦你完成了这个设置,而不仅仅是一个弹出窗口,FastMM将为你提供一个非常详细的内存泄漏报告,包括堆栈跟踪。这应该可以帮助您缩小正在进行的范围。
答案 2 :(得分:1)
正如梅森所说,FastMM4是你的朋友。您可能需要查看此CodeRage 2会话:Fighting Memory Leaks for Dummies。它主要说明如何使用FastMM来防止/检测Delphi中的内存泄漏。是D2007,但仍然相关。
至于为什么运行两次泄漏但没有运行一次,根据经验,这主要是由于在字段/变量中创建和存储对象而不首先检查是否已分配,泄漏先前的引用。构造如下:
TSomething
FMyObject: TMyObject;
[..]
TSomething.Destroy;
begin
FMyObject.Free;
end;
[...]
//somewhere in code:
FMyObject := TMyObject.Create; //leaks the previous FMyObject
显然不是那么直截了当,可能隐藏在某些setter中或通过某种List /容器......这里我猜想在不检查的情况下添加到VirtualTreeView ......