使用 VirtualTreeview 和 OTL 的内存泄漏

发布于 2024-09-27 11:41:08 字数 771 浏览 8 评论 0原文

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

I had created a small multi threaded application and I am trying to convert it to use OmniThreadLibrary. I am using the Virtualtreeview to display a log and the status/results. The Vst Log only has two columns and the record contains just two string fields (extremely simple, no objects inside the record).

Using a DEMO project that comes with OTL (thread pool #11) I changed the project to use a VirtualTreeview instead of the listbox. When I "Run Task" from the demo there is no memory leak, but if I run "Run Task" more than once a memory leak will occur. A memory leak will occur if I run any task more than once. If I do not use the VirtualTreeView at all, no memory leaks occur at any time. Just when I use the VST and when a task is run more than once.

I do use the FreeNode event and clear the strings, and even tried using Finalize...

example:

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;

why do I get a memory leak when a task is run more than once?
Delphi 2010 with FastMM4
latest Virtualtreeview and OTL

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

栖竹 2024-10-04 11:41:08

NodeFree 事件仅针对Validated 节点调用,Validated 通常意味着显示一次或多次的节点(当调用 GetText 事件时)。 查看使用虚拟TreeView组件

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

The NodeFree event is only called for Validated nodes, validated usually means Nodes that are shown one or more times (when the GetText event was called). See Memory Leaks when using the Virtual TreeView Component

edit: you can confirm by checking your node count and counting the number of times the NodeFree event is called.

白日梦 2024-10-04 11:41:08

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

I don't know why that's happening specifically, but I know how you can find out: turn on FastMM's FullDebugMode. (You'll need to download the FastMM full version from SourceForge for this.) Turn on the option that gives you a memory leak report in a file, and make sure the project's generating a detailed map file. Once you've got this set up, instead of just a popup window, FastMM will give you a very detailed memory leak report, complete with stack traces. This should help you narrow down what's going on.

穿越时光隧道 2024-10-04 11:41:08

正如 Mason 所说,FastMM4 是你的朋友。您可能想看一下这个 CodeRage 2 会议:傻瓜式解决内存泄漏问题。主要展示了如何在Delphi中使用FastMM来预防/检测内存泄漏。适用于 D2007,但仍然相关。

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

TSomething
FMyObject: TMyObject;
[..]

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

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

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

As Mason said, FastMM4 is your friend here. You may want to give a look at this CodeRage 2 session: Fighting Memory Leaks for Dummies. It mainly shows how to use FastMM to prevent/detect memory leaks in Delphi. Was for D2007 but still relevant.

As for why running twice does leak but not running once, from experience, it's mostly due to creating and storing an Object in a Field/Variable without checking first if it was assigned, leaking the previous reference. Construct like this:

TSomething
FMyObject: TMyObject;
[..]

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

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

Obviously not as straightforward and probably hidden in some setters or through some kind of List/container... Here I'd guess adding to the VirtualTreeView without checking...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文