FastMM报告记录线程变量的内存泄漏

时间:2013-08-22 08:07:00

标签: delphi memory-leaks delphi-xe2 fastmm

FastMM报告以下代码片段的内存泄漏(UnicodeString),该代码片段使用带有字符串的记录线程变量:

program Project10;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  FastMM4,
  System.SysUtils;

type
  TContext = record
    Value : String;
  end;

threadvar
  Context : TContext;

begin
Context.Value := 'asdfsdfasfdsa';
end.

这是真正的内存泄漏还是在FastMM检查内存泄漏后才发生线程变量的清理?

更重要的是:我怎样才能抑制这些“内存泄漏”,因为它们会混淆可能发现的任何其他内存泄漏?

2 个答案:

答案 0 :(得分:7)

这是一个真正的泄漏。线程局部变量超出范围时不会最终确定。因为您的记录包含托管的字段,字符串字段,如果记录未完成,则与该字符串关联的堆分配内存将被泄露。

documentation明确表示这一点:

  

通常由。管理的动态变量   编译器(长字符串,宽字符串,动态数组,变体,   和接口)可以用threadvar声明,但编译器不会自动释放堆分配   每个执行线程创建的内存。如果你使用   这些数据类型在线程变量中,这是你的责任   之前从线程中处理内存   线程终止。

如果要插入泄漏,则需要在范围结束时最终确定变量。也就是说,因为线程正在终止。

Finalize(Context);

请注意,您必须从拥有该变量的线程中执行此代码,因为显然只有该线程可以访问该变量。

如果要禁止报告这些泄漏,请调用RegisterExpectedMemoryLeak。

如果在线程终止时无法执行代码,那么最好避免堆分配并使用固定长度的字符数组。很可能你满足了你的需求。

当线程终止时,你声称不能执行代码似乎很奇怪。如果你不能这样做,你如何能够在这些线程的上下文中执行任何代码。换句话说,为了发生泄漏,您必须在这些线程中执行您的代码。

答案 1 :(得分:0)

创建TContext的全局数组,然后在threadvar中存储属于您的线程的元素的索引。