Delphi动态数组包含哪些簿记数据?

Mas*_*ler 4 delphi overhead dynamic-arrays data-structures

这是一个检查内存分配的简单程序.使用任务管理器检查值之前和之后建议每个动态数组占用大小为1的20字节内存.元素大小为4,这意味着簿记数据的开销为16字节.

从查看system.pas,我可以找到一个-4字节的数组长度字段,以及-8字节的引用计数,但我似乎找不到任何对其他的引用8.任何人都知道他们做了什么?

示例程序:

program Project1;

{$APPTYPE CONSOLE}

type
   TDynArray = array of integer;
   TLotsOfArrays = array[1..1000000] of TDynArray;
   PLotsOfArrays = ^TLotsOfArrays;

procedure allocateArrays;
var
   arrays: PLotsOfArrays;
   i: integer;
begin
   new(arrays);
   for I := 1 to 1000000 do
      setLength(arrays^[i], 1);
end;

begin
  readln;
  allocateArrays;
  readln;
end.
Run Code Online (Sandbox Code Playgroud)

Uli*_*rdt 5

我也看了一下System.pas并注意到_DynArrayCopyRange中的GetMem调用支持你的分析:

已分配大小=计数*元素大小+ 2*Sizeof(Longint)

.因此,从任务管理器获得的数字可能不是很准确.您可以尝试Pointer(someDynArray) := nil检查FastMM报告的内存泄漏大小,以获得更可靠的数字.

编辑:我做了一个小测试程序:

program DynArrayLeak;

{$APPTYPE CONSOLE}

uses
  SysUtils;

procedure Test;
var
  arr: array of Integer;
  i: Integer;
begin
  for i := 1 to 6 do
  begin
    SetLength(arr, i);
    Pointer(arr) := nil;
  end;
end;

begin
  ReportMemoryLeaksOnShutdown := True;
  Test;
end.
Run Code Online (Sandbox Code Playgroud)

这产生了

  An unexpected memory leak has occurred. The unexpected small block leaks are:

  1 - 12 bytes: Unknown x 1
  13 - 20 bytes: Unknown x 2
  21 - 28 bytes: Unknown x 2
  29 - 36 bytes: Unknown x 1

它支持8字节开销理论.

  • 诊断Delphi内存使用时,任务管理器不准确.除了动态数组本身的开销之外,它没有考虑VCL内存管理器对其内部所需的额外开销.并且它没有考虑到内存管理器在它们被"释放"时缓存并重用内存块,因为它们没有返回到OS. (3认同)