Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Free Memory when Out-of-memory exception occurs in Delphi using SetLength

I have a piece of Delphi code

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;

The above code tries to allocate lots of memory and out-of-memory will be caught. The a=nil will be executed, but the memory isn't freed.

Is there a way to free the memory in the case of out-of-memory exception?

I tried SetLength(a, 0, 0, 0) and Finalize(a), and both won't work either.

like image 608
justyy Avatar asked Sep 29 '12 16:09

justyy


1 Answers

In general, it's not possible to recover from an out of memory error. At that point the heap is most likely corrupted. The appropriate response is to terminate the process.

In this specific case, the allocation is performed by DynArraySetLength in the System unit. This performs repeated allocations. Only as the last act of DynArraySetLength is the return value, a in your code above, actually assigned. And if errors occur in DynArraySetLength then the runtime makes no effort to tidy up. Which means that in case of failure, any memory allocated is leaked and cannot be recovered. You have no way to refer to it in order to free it.

You may think that DynArraySetLength should do more to tidy up. However, it's approach is justifiable. Since out of memory conditions invariably result in corrupt heap, attempts to tidy up would just prolong the agony. Once the heap is dead, there's no point in trying to deallocate memory.

like image 141
David Heffernan Avatar answered Oct 18 '22 09:10

David Heffernan