How to reserve memory for my application and leave a specified amount remaining?
Asked Answered
N

2

9

I'm planning an application which will involve loading many pictures at one time and thus requires a large chunk of memory. For example, I might have 50 image objects created at once, taking a total of 1GB of RAM. But when the user goes to load 20 more pictures, I'd like to make sure that amount of memory is already reserved and ready.

Now this part might seem a little backwards from normal. Rather than specifying how much memory my application shall reserve, instead I need to specify how much memory to leave free for other applications, and adjust my application's memory periodically according to this specification. I must say I've never worked with reserving memory at all, and especially won't know how to leave this remaining available memory.

So for example, if the computer has 2048 MB of RAM, and the option is set to leave 50 MB free for other applications, and there is already 10MB of RAM being used by other apps, then it should reserve 2048-50-10 = 1988 MB for my app.

The trouble I foresee is suppose the user opens another application which requires 1GB. My app has to catch this and shrink its self.

Does this even sound like a feasible approach? Basically, I need to make sure there is as much memory reserved as possible at any given time, while leaving a decent amount available for other apps. Would it make a significant impact on performance if I do this, or not much at all? I might be loading and unloading images at rapid paces, and I don't want it to reserve/free this memory on demand, I want it to stay reserved.

Ninon answered 23/12, 2011 at 22:7 Comment(5)
+1 This is a good question and I have absolutely no idea why it has downvotes.Loisloise
@David. I was about to ask the very same question. Downvoters: please provide a rationale or we would think it's just the work of some monkeys trying to rewrite Shakespeare...Bozuwa
This article is old, but it explains how SQL Server 2000 does it. You might be interested.. Just to note, all of the applications that I know of that act this way, have additional options for tuning memory usage.Sthilaire
This question seems vaguely silly to me, because we're discussing using gigabytes of memory, in a 32 bit Delphi 7 process. It seems a joke to ask about making a reservation for memory I don't want to allocate yet, but just want to rerserve. My computer has 16 gigs of ram, and so I don't see any reason why I would ever write a 32 bit application and make it use gigabytes of memory, any more than I would start writing a new game and make it using 16-bit MS-DOS. It's just silly. Nevertheless, +1 for asking an interesting question - I learned something. Thanks.Gimpel
For the record, I got this idea when looking at the way the Microsoft Exchange Information Store works. It does exactly this. It's rather a memory hog - no matter how much memory you have in that machine, it eats it all up and only leaves a sliver left. But when you open something else, it automatically shrinks its self to respectively allow that other app to open.Ninon
I
8

+1 for Sertac's mentioning of how SQL Server rides the line of allocating memory it needs, but releasing memory when Windows complains.

Applications can receive Window's complaints by using the CreateMemoryResourceNotification:

hLowMemory := CreateMemoryResourceNotification(LowMemoryResourceNotification);

Applications can use memory resource notification events to scale the memory usage as appropriate. If available memory is low, the application can reduce its working set. If available memory is high, the application can allocate more memory.

Any thread of the calling process can specify the memory resource notification handle in a call to the QueryMemoryResourceNotification function or one of the wait functions. The state of the object is signaled when the specified memory condition exists. This is a system-wide event, so all applications receive notification when the object is signaled. Note that there is a range of memory availability where neither the LowMemoryResourceNotification or HighMemoryResourceNotification object is signaled. In this case, applications should attempt to keep the memory use constant.

But it's also worth mentioning that you might as well allocate memory that you need. Your operating system has a very sophisiticated set of algorithms to swap out the least used memory when memory pressure is high. You can take advantage of this by simply allocating all the memory that you need. When Windows starts to run low, it will find those pages of memory that you are using the least and swap them out to disk. (This is how a well-known reverse proxy works).

The only thing left is to decide if you want to free some images when Windows says it's running low on RAM. But if you're not using the memory, it is going to be swapped out to disk for you.

Impressionable answered 24/12, 2011 at 4:7 Comment(3)
+1 and accepted :D I intend to deal with Windows complaints by pausing certain rendering of certain graphics, or by lowering the resolution of how it renders. I have layers upon layers of images to combine into one master image (laid out a little like an OS). Basically I have a "Desktop" simulation with custom drawn windows, etc and paint handling, etc. Much like how Windows handles paint commands via Invalidate;Ninon
And thanks for the Christmas present Ian, Sertac, and David :PNinon
Anyone else tried this to see if it actually works? When I tried using QueryMemoryResourceNotification and I never get a notification - even when processes are hanging due to waiting to allocate memory.Timorous
L
7

It's not realistic to account for other apps. Just ignore them. The system will page things in and out as needed. If you really wanted to do this you'd have to dynamically adapt to other processes as they start and finish. That's really not realistic. What's more it's not practical to inquire of other processes how much memory they need. Leave it all to the system.

Set a budget for your app and make sure you don't exceed it. Keep the most recently used images in memory and when you approach your memory budget throw away the least recently used images to make space.

If you are stressing the available resources then make sure you use FastMM and enable LARGE_ADDRESS_AWARE for your app so that you get 4GB address space when running on a 64 bit OS.

Loisloise answered 23/12, 2011 at 22:11 Comment(4)
+1 Thanks, that makes sense. I regret to say I still have not tried FastMM yet, but plan to very soon. I understand it's practically an essential for Delphi 7.Ninon
Yep. It's OS' business here. All you can do is avoiding being greedy/careless with memory.Bozuwa
Not only do you need it for LARGE_ADDRESS_AWARE, it can even find dangling pointer access! ;-)Loisloise
Yes, yes, yes :P I think you made yourself extremely clear in my previous question. I do in fact write my applications and projects to the point where I shouldn't have to worry about it, but I never know if I give this to someone else, how much would they screw it up, not knowing how it works.Ninon

© 2022 - 2024 — McMap. All rights reserved.