将本地动态数组的长度设置为零是否会减少内存使用量?



将本地动态数组的长度设置为零(不再需要时(是否有内存使用优势?

例如:

var
MyArray : array of string;
begin
<filling my array with a lot of items....>
<doing some stuffs with MyArray>
//from here on, MyArray is no more needed, should I set its length to zero?
SetLength(MyArray, 0);
<doing other stuffs which doesn't need MyArray...>
end;

在Delphi中,动态数组是引用计数的。

因此,如果你做

MyArray := nil;

Finalize(MyArray);

SetLength(MyArray, 0);

变量MyArray将不再指向动态数组堆对象,因此其引用计数将减少1。如果这使得引用计数降至零,意味着没有变量指向它,那么它将被释放。

示例1

所以在中

var
a: array of Integer;
begin
SetLength(a, 1024*1024);
// ...
SetLength(a, 0);
// ...
end

您将释放SetLength(a, 0)上的内存,假设a是指向该堆对象的唯一变量

示例2

var
b: TArray<Integer>;
procedure Test;
var
a: TArray<Integer>;
begin
SetLength(a, 1024*1024);
b := a;
SetLength(a, 0);
// ...
end

SetLength(a, 0)不会释放任何内存,因为b仍在引用原始数组。不过,它会将引用计数从2减少到1。

示例3

当然,在

var
a: array of Integer;
begin
SetLength(a, 1024*1024);
// ...
SetLength(a, 0);
end

SetLength的最后一次调用是完全不必要的,因为局部变量a无论如何都会在下一行代码中超出作用域,这也减少了堆对象的refcount。

是的,当您将动态数组的长度设置为零时,如果没有其他变量/对象引用内存,则它正在使用的内存会释放回可用的堆内存(不一定要回到Windows内存,所以你可能看不到任务管理器的好处,但你的Delphi程序需要更长的时间才能从Windows分配额外的内存,因为它将首先使用可用的堆内存,你已经添加了"MyArray"的大小(。

相关内容

最新更新