开发者

SetProcessWorkingSetSize - What's the catch?

开发者 https://www.devze.com 2023-03-07 13:19 出处:网络
I found an article on About.com that tells you how you can manage your apps memory. Here is the code: procedure TrimAppMemorySize;

I found an article on About.com that tells you how you can manage your apps memory.

Here is the code:

procedure TrimAppMemorySize;
var
  MainHandle : THandle;
begin
  try
    MainHandle := OpenProcess(PROCESS_ALL_ACCESS, false, GetCurrentProcessID) ;
    SetProcessWorkingSetSize(MainHandle, $FFFFFFFF, $FFFFFFFF) ;
    CloseHandle(MainHandle) ;
    Log('Trimmed Memory Successfull!');
  except
    Log('Failed to trim Memory!');
  end;
  Application.ProcessMessages;
end;

I tried it out, works perfectly - Even when my app is doing something, and I fire buttonclicks, etc, it still does its thing, and it works like a charm. I look at my apps Memory usage in the Resource Monitor, and as far as I can see, its all good.

So.. Whats the catch? We all deal with memory issues, but is the solution really that simple? Can anyone tell me if doing this every 60 seconds is a bad thing?

I will re开发者_开发知识库boot and try to run my program, and post a screenshot of my Resource Monitor.


Yes, it's a bad thing. You're telling the OS that you know more about memory management than it does, which probably isn't true. You're telling to to page all your inactive memory to disk. It obeys. The moment you touch any of that memory again, the OS has to page it back into RAM. You're forcing disk I/O that you don't actually know you need.

If the OS needs more free RAM, it can figure out which memory hasn't been used lately and page it out. That might be from your program, or it might be from some other program. But if the OS doesn't need more free RAM, then you've just forced a bunch of disk I/O that nobody asked for.

If you have memory that you know you don't need anymore, free it. Don't just page it to disk. If you have memory that the OS thinks you don't need, it will page it for you automatically as the need arises.

Also, it's usually unwise to call Application.ProcessMessages unless you know there are messages that your main thread needs to process that it wouldn't otherwise process by itself. The application automatically processes messages when there's nothing else to do, so if you have nothing to do, just let the application run itself.


The "catch" as it were is that you have just told the operating system to remove pages from your working set that are actually in RAM. Assuming the OS is removing pages that don't have data you will ever access again, there's no problem. But if it's paging out data that your process will need in the future, you've just told Windows "More page faults, please."

The main issue with this code is that you're essentially sacrificing your own process's performance for the sake of the rest of the system (though thrashing actually harms the whole system.) That's somewhat noble, but clearly not "catch" free.


This is the moral equivalent of pretending to the operating system that your machine is an permanent state of RAM crisis. The system knows how to manage its memory far better than you do, just let it get on with its job.

It is, sadly, a very common mistake for people to worry when their system is using all of its RAM and all of its CPU. In reality you should be concerned if your system fails to make full use of its resources!


Actually when using GlobalAlloc/GlobalFree Windows does tend to keep those memory blocks attached to your process, I have had process "appear" to be using 400MB of memory when it was only using 40MB because GlobalFrees do not really release the memory back (we are talking along lived process running in the background as long as the machine is running). In this case I found it very useful to have the ability to tell Windows compact the process memory. I do use the GetProcessMemoryInfo and check the current .WorkingSetSize, if larger than a certain amount (like 100MB) the memory is compacted. Yes, this does incur page faults for memory being actively used but memory is freed back to the kernel for use by other processes.

So, in some cases I found that Windows does not do a good job "garbage collecting" and returning resources. Glad this call is available, it is very useful.

0

精彩评论

暂无评论...
验证码 换一张
取 消