3

我创建了一个小型多线程应用程序,我正在尝试将其转换为使用 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

4

3 回答 3

11

NodeFree 事件仅对Validated节点调用,已验证通常意味着显示一次或多次的节点(调用 GetText 事件时)。请参阅使用 Virtual TreeView 组件时的内存泄漏

编辑:您可以通过检查节点计数并计算调用 NodeFree 事件的次数来确认。

于 2010-10-14T06:16:38.133 回答
4

我不知道为什么会发生这种情况,但我知道你怎么能找到:打开 FastMM 的 FullDebugMode。(为此,您需要从 SourceForge 下载 FastMM 完整版。)打开在文件中提供内存泄漏报告的选项,并确保项目正在生成详细的映​​射文件。一旦你完成了这个设置,而不仅仅是一个弹出窗口,FastMM 会给你一个非常详细的内存泄漏报告,包括堆栈跟踪。这应该可以帮助您缩小范围。

于 2010-10-13T18:39:00.760 回答
1

正如 Mason 所说,FastMM4是你的朋友。您可能想看看这个 CodeRage 2 会议:为傻瓜而战的内存泄漏。它主要展示了如何使用 FastMM 来防止/检测 Delphi 中的内存泄漏。适用于 D2007,但仍然相关。

至于为什么运行两次确实泄漏但没有运行一次,从经验来看,这主要是由于在字段/变量中创建和存储对象而没有先检查它是否被分配,泄漏了之前的引用。像这样构造:

TSomething
FMyObject: TMyObject;
[..]

TSomething.Destroy;
begin
  FMyObject.Free;
end;
[...]

//somewhere in code:
FMyObject := TMyObject.Create; //leaks the previous FMyObject

显然不是那么简单,可能隐藏在一些设置器中或通过某种列表/容器......在这里我猜想添加到 VirtualTreeView 而不检查......

于 2010-10-13T23:02:52.133 回答