델파이 동적 배열에는 어떤 부기 데이터가 포함되어 있습니까?
-
19-09-2019 - |
문제
다음은 메모리 할당을 확인하는 간단한 프로그램입니다. 작업 관리자와의 값 전후에 확인하면 각 동적 배열이 크기 = 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;