Delphi中的数组可用内存

alp*_*sin -4 memory arrays delphi pascal record

使用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;
Run Code Online (Sandbox Code Playgroud)

在释放我正在使用此过程:

 procedure TElem.FreeElem;
 begin
 SetLength(Self.aXY.points,0);
 Self.aXY.points:=nil;
 end;
Run Code Online (Sandbox Code Playgroud)

Dav*_*nan 6

管理动态数组,并在系统范围结束时由系统自动释放.所以你实际上并不需要明确地释放它们.当然,如果您希望在范围结束之前释放它们,您可以这样做.它足以做到:

SetLength(aXY.points, 0);
Run Code Online (Sandbox Code Playgroud)

要么

aXY.points := nil;
Run Code Online (Sandbox Code Playgroud)

要么

Finalize(aXY.points);
Run Code Online (Sandbox Code Playgroud)

这三个陈述中的每一个都是相同的.你可以选择其中一个,但没有必要做多个.例如,这足以:

procedure TElem.FreeElem;
begin
  aXY.points := nil;
end;
Run Code Online (Sandbox Code Playgroud)

这些都没有解释为什么你有泄漏.正如我所解释的那样,动态数组是受管理的,因此当它们的范围结束时,它们将被销毁.

对此的明显结论是动态数组的范围永远不会结束.如果您的代码泄露了TElem实例,那就会发生.如果您未能销毁TElem拥有该阵列的实例,那么阵列本身将不会被销毁,并且会泄漏.

泄漏的另一个原因可能是数组的元素本身就是托管类型.Move执行"盲"内存副本并绕过阵列中任何托管类型的生命周期管理.如果您的数组元素具有托管类型(字符串,动态数组,接口等),则使用Move是错误的.

  • 如果我不得不猜测,我认为你很可能不会破坏`TElem`实例.不要让我们猜.提供[mcve]. (4认同)