下面是一个检查内存分配的简单程序。使用任务管理器检查前后的值表明,当大小= 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.发布于 2009-12-15 09:25:52
内存分配具有粒度,以确保所有分配都是对齐的。这就是由它引起的问题。
发布于 2009-12-15 06:23:25
已更新...我实际上去检查了代码(我之前就应该这么做了),我得出了和Ulrich一样的结论,它没有存储任何类型信息,只存储了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;https://stackoverflow.com/questions/1903664
复制相似问题