【问题标题】:Memory Leak using VirtualTreeview and OTL使用 VirtualTreeview 和 OTL 的内存泄漏
【发布时间】:2010-10-13 18:25:23
【问题描述】:

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

为什么在多次运行任务时会出现内存泄漏? 带有 FastMM4 的 Delphi 2010 最新的 Virtualtreeview 和 OTL

【问题讨论】:

  • 创建一个展示此行为的小程序并将其发布到 OTL 论坛 (otl.17slon.com/forum)。我随时为您提供帮助。
  • 我打算在你的论坛上发帖,但我很确定这是虚拟树视图的问题,而事实证明问题出在 VTreeview 上。顺便说一句,谢谢你的 OTL

标签: delphi virtualtreeview omnithreadlibrary


【解决方案1】:

NodeFree 事件仅对 Validated 节点调用,已验证通常意味着显示一次或多次的节点(调用 GetText 事件时)。 See Memory Leaks when using the Virtual TreeView Component

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

【讨论】:

  • 你是对的,如果你在创建节点后输入以下内容,内存泄漏就消失了:“vst1.ValidateNode(aNode, False);”我之前在 vst 中更新节点时使用过 ValidateNode,但我从未见过在创建节点时使用过它……在任何演示和教程中都没有。谢谢。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

    至于为什么运行两次会泄漏但不会运行一次,根据经验,这主要是由于在Field/Variable中创建并存储了一个Object而没有先检查它是否被分配,泄漏了之前的引用。像这样构造:

    TSomething
    FMyObject: TMyObject;
    [..]
    
    TSomething.Destroy;
    begin
      FMyObject.Free;
    end;
    [...]
    
    //somewhere in code:
    FMyObject := TMyObject.Create; //leaks the previous FMyObject
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多