5

We have an application that could potentially allocate a large number of small objects (depending on user input). Sometimes the application runs out of memory and effectively crashes.

However, if we knew that memory allocations were becoming tight there are some lower-priority objects which could be destroyed and thereby allow us to gracefully degrade the user results.

What's the best way to detect that memory for a process is running low before calls to 'new' actually fail? We could call API functions like GetProcessWorkingSetSize() or GetProcessMemoryInfo() but how do you know when the limits on a given machine are being reached (e.g. with 80% of maximum allocations)?

snowdude
  • 3,854
  • 1
  • 18
  • 27
  • 1
    Unless your disk is nearly full, the problem isn't in the amount of free memory on the machine (because you have virtual, on-disk memory), but address space fragmentation due to those objects and possible memory leaks. – Alexey Frunze Aug 12 '12 at 12:37
  • @AlexeyFrunze On 32-bit Windows memory allocations seem to start failing around 1.5GB. It's not memory leaks, we can account for all used memory, but I take your point about fragmentation. – snowdude Aug 13 '12 at 09:00

3 Answers3

5
  • At start up, allocate a memory reserve.
  • Then use set_new_handler() to install a hook that will detect allocations failures.
  • When one happens:
    • Free the reserve (so you have enough free memory to work with).
    • Run your code that finds and frees low priority objects.
    • When that has done its job, try to reallocate the reserve again (for next time).
    • Finally return to let the original allocation attempt retry.
Brangdon
  • 627
  • 5
  • 7
2

If it's a 32-bit process then you would want to ensure that you don't use more than 1.6GB, which is 80% of 2.0GB, the max allowed for your process. Calling GlobalMemoryStatusEx will fill in the struct MEMORYSTATUSEX.ullAvailVirtual, when this is only 400MB available (or less) then you are at your threshold.

Chris O
  • 5,017
  • 3
  • 35
  • 42
0

Check this answer Win32/MFC: How to find free memory (RAM) available?.

You need to periodically find available free memory and stop allocating at some limit. As explained in above referred answer, you can use GlobalMemoryStatusEx, and/or VirtualQueryEx.

Community
  • 1
  • 1
Rohan
  • 52,392
  • 12
  • 90
  • 87
  • Not usually a good idea. See http://blogs.msdn.com/b/oldnewthing/archive/2012/01/18/10257834.aspx – Harry Johnston Aug 13 '12 at 05:57
  • @HarryJohnston good point. But that is the question or this particular answer? – Rohan Aug 13 '12 at 06:13
  • I think our problem is subtly different. We don't care about global system resources we just want to know when the OS is about to stop allocating OUR program memory so we can do something about it before it's too late. – snowdude Aug 13 '12 at 09:08