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检查内存泄漏后才清理线程变量?
更重要的是:当这些"内存泄漏"扰乱了可能发现的任何其他内存泄漏时,我如何才能抑制这些"内存泄露"的报告?
这是一个真正的泄漏。线程局部变量超出作用域时不会最终确定。因为您的记录包含一个被管理的字段,即字符串字段,如果记录没有最终确定,则与该字符串相关联的堆分配内存会泄漏。
文档明确指出:
通常由编译器(长字符串、宽字符串、动态数组、变体、,和接口)可以用threadvar声明,但编译器不会自动释放分配的堆由每个执行线程创建的内存。如果您使用线程变量中的这些数据类型,由您负责在线程终止。
如果你想堵住漏洞,你需要在作用域结束时完成变量。也就是说,线程正在终止。
Finalize(Context);
请注意,您必须从拥有变量的线程执行此代码,因为很明显,只有该线程才能访问它
如果您想禁止报告这些泄漏,请调用RegisterExpectedMemoryLeak。
如果在线程终止时无法执行代码,那么最好避免堆分配并使用固定长度的字符数组。很可能你满足了你的需求。
当线程终止时,您声称无法执行代码,这似乎很奇怪。如果你不能做到这一点,你如何能够在这些线程的上下文中执行任何代码。换句话说,为了发生泄漏,您必须在这些线程中执行了代码。
创建TContext的全局数组,然后将属于线程的元素的索引存储在threadvar中。