Какие бухгалтерские данные содержит динамический массив Delphi?

StackOverflow https://stackoverflow.com/questions/1903664

Вопрос

Вот простая программа для проверки распределения памяти. Проверка значений до и после менеджера задач предполагает, что каждый динамический массив занимает 20 байтов памяти при размере = 1. Размер элемента составляет 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.
Это было полезно?

Решение

Я также посмотрел на систему. PAS и заметил, что вызов getMem в _dynarraycopyrange поддерживает ваш анализ:

выделенный размер = count * Размер элемента + 2 * sizeof (longint)

. Анкет Так что, возможно, цифры, которые вы получаете от Manager Task Manager, не очень точны. Вы могли бы попробовать 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.

Это дает

  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 байтов.

Другие советы

Распределение памяти обладает детализацией, чтобы гарантировать, что все распределения выровнены. Это просто склон, вызванный этим.

Обновлено ... Я на самом деле пошел проверить код (что я должен был сделать раньше), и я пришел к тому же выводу, что и Ульрих, он не хранит информацию о какой -либо типах, только 2 накладных расходах Longint, затем nbelements*Elementsize.
И менеджер задач не является точным для такого рода меры.

С странностью, что если вы измеряете память, используемую Dynarray, она увеличивается не линейно с размером элемента: для записи с 2 или 3 целыми числами это такой же размер (20), с 4 или 5 это 28 ... Следуя гранулярности блоков.

Память измерена с помощью:

// Return the total Memory used as reported by the Memory Manager
function MemoryUsed: Cardinal;
var
  MemMgrState: TMemoryManagerState;
  SmallBlockState: TSmallBlockTypeState;
begin
  GetMemoryManagerState(MemMgrState);
  Result := MemMgrState.TotalAllocatedMediumBlockSize + MemMgrState.TotalAllocatedLargeBlockSize;
  for SmallBlockState in MemMgrState.SmallBlockTypeStates do begin
      Result := Result + SmallBlockState.UseableBlockSize * SmallBlockState.AllocatedBlockCount;
  end;
end;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top