使用FastMM4时,函数DynArraySetLength中的system.pas存在内存泄漏。我正在使用一个列表,其中每个元素有5条记录。这些记录依次列出数百万的订单。因此,小内存泄漏积累为巨大的块。
在释放元素的同时,我故意使用SetLength(x,0)和x:= nil。但是,在system.pas的DynArraySetLength中仍然存在内存泄漏。有人可以建议我如何使用有效的方式释放阵列,并克服这个内存泄漏。
提前致谢
代码:此过程的SetLength发生内存泄漏
procedure TElem.Assign(Value: TElem);
begin
SetLength(Self.aXY.points, Length(Value.aXY.points)); //MEMORY LEAK
Move(Value.aXY.points[0], Self.aXY.points[0],
Length(Value.aXY.points) * SizeOf(coordinate));
end;
在释放我正在使用此过程:
procedure TElem.FreeElem;
begin
SetLength(Self.aXY.points,0);
Self.aXY.points:=nil;
end;
管理动态数组,并在系统范围结束时由系统自动释放。所以你实际上并不需要明确地释放它们。当然,如果您希望在范围结束之前释放它们,您可以这样做。它足以做到:
SetLength(aXY.points, 0);
要么
aXY.points := nil;
要么
Finalize(aXY.points);
这三个陈述中的每一个都是相同的。你可以选择其中一个,但没有必要做多个。例如,这足以:
procedure TElem.FreeElem;
begin
aXY.points := nil;
end;
这些都没有解释为什么你有泄漏。正如我所解释的那样,动态数组是受管理的,因此当它们的范围结束时,它们将被销毁。
对此的明显结论是动态数组的范围永远不会结束。如果您的代码泄露了TElem
实例,就会发生这种情况。如果你没有销毁拥有该数组的TElem
实例,那么数组本身不会被破坏,并且会泄漏。
泄漏的另一个原因可能是数组的元素本身就是托管类型。 Move
执行“盲”内存复制并绕过阵列中任何托管类型的生命周期管理。如果你的数组元素有托管类型(字符串,动态数组,接口等),那么使用Move
是一个错误。