Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get available memory (address space) before EOutOfMemory in a Delphi application

I have a 32-bit Delphi application running with /LARGEADDRESSAWARE flag on. This allows to allocate up to 4GB on a 64-bit system.

Am using threads (in a pool) to process files where each task loads a file in memory. When multiple threads are running (multiple files being loaded), at some point the EOutOfMemory hits me.

What would be the proper way to get the available address space so I can check if I have enough memory before processing the next file?

Something like:

if TotalMemoryUsed {from GetMemoryManagerState} + FileSize < "AvailableUpToMaxAddressSpace" then NoOutOfMemory

I've tried using

TMemoryStatusEx.ullAvailVirtual for AvailableUpToMaxAddressSpace

but the results are not correct (sometimes 0, sometimes > than I actually have).

like image 789
Torpedo Avatar asked Nov 01 '22 15:11

Torpedo


2 Answers

I don't think that you can reasonably and robustly expect to be able to predict ahead of time whether or not memory allocations will fail. At the very least you would probably need to write your own memory allocator that was dedicated to serving your application, and have a very strong understanding of the heap allocation requirements of your process.

Realistically the tractable way forward for you is to break free from the shackles of 32 bit address space. That is your fundamental problem. The way to escape from 32 bit address space is to compile for 64 bit. That requires XE2 or later.

You may need to continue supporting 32 bit versions of your application because you have users that are still on 32 bit systems. The modern versions of Delphi have 32 bit and 64 bit compilers and it is quite simple to write code that will compile and behave correctly under both scenarios.

For your 32 bit versions you are less likely to run into memory problems anyway because 32 bit systems tend to run on older hardware with fewer processors. In turn this means less demand on memory space because your thread pool tends to be smaller.

If you encounter machines with large enough processor counts to cause out of memory problems then one very simple and pragmatic approach is to give the user a mechanism to limit the number of threads used by your application's thread pool.

like image 150
David Heffernan Avatar answered Nov 15 '22 13:11

David Heffernan


Since there are more processes running on the target system even if the necessary infrastructure would be available, if would be no use.


There is no guarantee that another process does not allocate the memory after you have checked its availability and before you actually allocate it. The right thing to do is writing code that will fail gracefully and catch the EOutOfMemory exception when it appears. Use it as a sign to stop creating more threads until some of them is already terminated.

like image 31
mg30rg Avatar answered Nov 15 '22 11:11

mg30rg