문제

다음은 메모리 할당을 확인하는 간단한 프로그램입니다. 작업 관리자와의 값 전후에 확인하면 각 동적 배열이 크기 = 1에서 20 바이트의 메모리를 차지한다고 제안합니다. 요소 크기는 4이며, 이는 부기 데이터에 대해 16 바이트의 오버 헤드를 의미합니다.

System.PAS를 통해 -4 바이트에서 배열 길이 필드와 -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.
도움이 되었습니까?

해결책

나는 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.

이것은 수율입니다

  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 바이트 오버 헤드 이론을 지원합니다.

다른 팁

메모리 할당은 모든 할당이 정렬되도록 세분성을 가지고 있습니다. 이것은 이것으로 인한 슬로프입니다.

업데이트되었습니다 ... 실제로 코드를 확인하러갔습니다 (이전에 해왔으므로) Ulrich와 같은 결론을 내 렸습니다. 유형 정보를 저장하는 것이 아닙니다.
또한 작업 관리자는 이러한 종류의 측정에 대해 정확하지 않습니다.

Dynarray가 사용하는 메모리를 측정하면 요소의 크기로 선형으로 증가하지 않는다는 이상한 점에서 2 또는 3 정수의 레코드의 경우 4 또는 5의 크기 (20)와 같은 크기 (20)입니다. 블록 크기의 세분성에 따라.

메모리 측정 :

// 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