动态数组是引用计数的,因此编译器会自动释放内存。我的问题是,什么时候发生这种自动释放?它会立即发生,还是在包含程序结束时发生?
这是一个具体的例子
procedure DoStuff;
var data:TBytes;
begin
data:=GetData; // lets say data now contains 1 Gig of data.
DoStuffWithData(data);
// I now want to free up this 1Gig of memory before continuing.
// Is this call needed, or would the memory be freed in the next line anyway?
Finalize(data);
data:=GetMoreData; // The first array now has no remaining references
DoStuffWithData(data);
end
对Finalize()的调用是否冗余?
答案 0 :(得分:11)
对Finalize
的调用并不是多余的。确实,动态数组的引用计数将在下一行递减(因此可能会破坏数组),但这只会在分配新动态数组后发生。在返回GetMoreData
之前,但在分配之前,内存中将有两个动态数组。如果你事先手动销毁第一个,那么你一次只能在内存中有一个数组。
存储在data
中的第二个数组将在DoStuff
返回时被销毁(假设DoStuffWithData
未存储动态数组的副本参考其他地方,增加其参考数量。)
答案 1 :(得分:1)
何时发生这种自动释放?是立即发生,还是在包含程序结束时发生?
当引用计数设置为0时,将释放与托管类型(动态数组属于此类)关联的动态内存。这可能发生在以下几点:
请注意,上述各种情况仅导致在正在完成或正在离开作用域的引用是最后剩余引用时释放内存。换句话说,当引用计数为1时。
在您的特定示例中,假设删除了Finalize,您将创建一个新的动态数组并将其分配给已拥有动态数组的变量。然后它落入上面列表中第1项描述的类中。因此,在这种意义上,对Finalize的调用是多余的。
Rob已经解释了分配和释放发生的顺序,这是一个好点。据我所知,这是一个未明确记录的实现细节。但是,如果细节有所改变,我会感到震惊。