如何使用SetLength在Delphi中发生内存不足异常时释放内存
我有一段Delphi代码如何使用SetLength在Delphi中发生内存不足异常时释放内存,delphi,memory,free,multidimensional-array,Delphi,Memory,Free,Multidimensional Array,我有一段Delphi代码 var a: array of array of array of integer; begin try SetLength(a, 100000, 100000, 10000); // out of memory here doStuffs(a); except a = nil; // try to free the memory end; end; 上面的代码试图分配大量内存,并且内存不足将被捕获。将执行a=nil,但不会释放内
var
a: array of array of array of integer;
begin
try
SetLength(a, 100000, 100000, 10000); // out of memory here
doStuffs(a);
except
a = nil; // try to free the memory
end;
end;
上面的代码试图分配大量内存,并且内存不足
将被捕获。将执行a=nil
,但不会释放内存
在出现内存不足异常的情况下,是否有办法释放内存
我尝试了
SetLength(a,0,0,0)
和Finalize(a)
,但两者都不起作用。一般来说,无法从内存不足错误中恢复。此时,堆很可能已损坏。适当的反应是终止该过程
在此特定情况下,分配由系统
单元中的DynArraySetLength
执行。这将执行重复分配。只有当DynArraySetLength
的最后一个动作是返回值时,上面代码中的a
才被实际赋值。如果在DynArraySetLength
中发生错误,那么运行时将不进行整理。这意味着在发生故障的情况下,任何分配的内存都会泄漏,无法恢复。你没有办法参考它来释放它
您可能认为
DynArraySetLength
应该做更多的整理工作。然而,它的方法是合理的。由于内存不足的情况总是导致堆损坏,因此尝试清理只会延长痛苦。一旦堆死了,尝试释放内存就没有意义了。接下来的自然问题是“有TrySetLength
过程吗?”@AndreasRejbrand没有。你确定吗?它认为堆是否损坏取决于内存管理器内部。@Serg不适用于多维数组的SetLength。老实说,我不认为任何常用的彩信都能适应OOM。@AndreasRejbrand您可以创建这样一个函数,但是您需要编写自己的DynArraySetLength
,以使其更加健壮。一个更简单(但不是竞争条件证明)的方法是检查内存是否可用,然后分配它。当您在异常处理程序中时,A
甚至有一个非空值吗?如果没有,那么你很难期望能够释放它。此外,它将在函数结束时被释放。您是否确认SetLength
在无法完成分配所有请求的内存时设置a
变量?@Rob No,a
在异常处理程序中为nil
。是的,当代码进入异常块时,a=nil。PS:我使用FastMM作为内存管理器。在这种情况下,除非程序退出,否则内存不会被释放。