使用FastMM4时,system.pas在函数DynArraySetLength中存在内存泄漏。我正在使用一个列表,其中每个元素都有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;
答案 0 :(得分:6)
动态数组是受管理的,因此在其作用域结束时由系统自动释放。因此,您实际上不需要显式释放它们。当然,如果您希望在它们的作用域结束之前释放它们,则可以这样做。可以做到:
SetLength(aXY.points, 0);
或
aXY.points := nil;
或
Finalize(aXY.points);
这三个语句中的每一个都是相同的。您可以选择其中之一,但是做不止一项是没有意义的。例如,满足以下条件:
procedure TElem.FreeElem;
begin
aXY.points := nil;
end;
以上所有内容均无法解释您泄漏的原因。正如我所解释的,动态数组是受管理的,因此当它们的作用域结束时,它们将被销毁。
一个明显的结论是动态数组的范围永无止境。如果您的代码泄漏了TElem
个实例,那将会发生。如果您无法销毁拥有该数组的TElem
实例,那么这些数组本身将不会被销毁,并且会泄漏。
另一个导致泄漏的原因可能是数组的元素本身是托管类型。 Move
执行“盲”内存复制,并绕过阵列中任何托管类型的生命周期管理。如果您的数组元素具有托管类型(字符串,动态数组,接口等),那么使用Move
是错误的。