使用VirtualTreeview和OTL出现内存泄漏问题

3

我创建了一个小型的多线程应用程序,并尝试将其转换为使用OmniThreadLibrary。我正在使用Virtualtreeview来显示日志和状态/结果。Vst Log只有两列,记录只包含两个字符串字段(非常简单,没有记录内部的对象)。

使用OTL附带的DEMO项目(线程池#11),我将该项目更改为使用VirtualTreeview而不是listbox。当我从演示文稿中“运行任务”时,没有内存泄漏,但如果我运行“运行任务”超过一次,就会发生内存泄漏。如果我运行任何任务超过一次,都会发生内存泄漏。如果根本不使用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。

3
创建一个能够展示这种行为的小程序,并将其发布到OTL论坛(http://otl.17slon.com/forum)。我会一直在那里提供帮助。 - gabr
我本来想在你的论坛上发帖,但我相当确定这是Virtual Treeview的问题,结果证明问题出在VTreeview上。顺便说一句,感谢OTL。 - Logman
3个回答

11

1
你是正确的,如果在创建节点后加入以下代码,内存泄漏问题就会解决:“vst1.ValidateNode(aNode, False);” 我之前在更新VST中的节点时使用过ValidateNode,但我从未见过在创建节点时使用它...无论是在任何演示或教程中都没有。谢谢。 - Logman

4
我不知道为什么会出现这种情况,但我知道如何找到原因:打开FastMM的FullDebugMode(您需要从SourceForge下载FastMM完整版本才能使用此功能)。打开选项以将内存泄漏报告保存在文件中,并确保项目生成了详细的映射文件。一旦设置完成,FastMM将会提供一个非常详细的内存泄漏报告,包括堆栈跟踪。这应该能帮助您缩小问题范围。

1

正如Mason所说,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

显然不是那么直接的,可能隐藏在某些设置器或通过某种列表/容器中... 在这里,我猜测是在没有检查的情况下添加到VirtualTreeView中...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接