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检查内存泄漏之后才对线程变量进行清理?
更重要的是:当这些“内存泄漏”扰乱了可能发现的任何其他内存泄漏时,我如何才能抑制这些“内存泄漏”呢?
发布于 2013-08-22 08:37:12
这是个真正的泄漏。线程局部变量在超出作用域时尚未最后确定。因为您的记录包含一个被管理的字段,如果该记录尚未完成,则string字段、与该字符串关联的堆分配内存将被泄漏。
documentation显式地调用它:
通常由编译器管理的动态变量(长字符串、宽字符串、动态数组、变体和接口)可以用三进声明,但编译器不会自动释放每个执行线程创建的堆分配内存。如果在线程变量中使用这些数据类型,则在线程终止之前,您有责任从线程中释放它们的内存。
如果要堵塞泄漏,则需要在作用域结束时最后确定变量。也就是说,当线程正在终止时。
Finalize(Context);请注意,您必须从拥有变量的线程执行此代码,因为显然,只有该线程才能访问它。
如果您想阻止这些泄漏的报告,那么请调用RegisterExpectedMemoryLeak。
如果线程终止时无法执行代码,则最好避免堆分配,并使用固定长度的字符数组。很有可能你满足了你的需要。
当线程终止时,您声称无法执行代码,这似乎很奇怪。如果不能这样做,如何能够在这些线程的上下文中执行任何代码。换句话说,为了防止泄漏,您必须在这些线程中执行您的代码。
发布于 2013-08-22 11:24:14
创建TContext的全局数组,然后将属于线程的元素的索引存储在三个高级中。
https://stackoverflow.com/questions/18374879
复制相似问题