Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preventing a heavy process from sinking in the swap file

Our service tends to fall asleep during the nights on our client's server, and then have a hard time waking up. What seems to happen is that the process heap, which is sometimes several hundreds of MB, is moved to the swap file. This happens at night, when our service is not used, and others are scheduled to run (DB backups, AV scans etc). When this happens, after a few hours of inactivity the first call to the service takes up to a few minutes (consequent calls take seconds).

I'm quite certain it's an issue of virtual memory management, and I really hate the idea of forcing the OS to keep our service in the physical memory. I know doing that will hurt other processes on the server, and decrease the overall server throughput. Having that said, our clients just want our app to be responsive. They don't care if nightly jobs take longer.

I vaguely remember there's a way to force Windows to keep pages on the physical memory, but I really hate that idea. I'm leaning more towards some internal or external watchdog that will initiate higher-level functionalities (there is already some internal scheduler that does very little, and makes no difference). If there were a 3rd party tool that provided that kind of service is would have been just as good.

I'd love to hear any comments, recommendations and common solutions to this kind of problem. The service is written in VC2005 and runs on Windows servers.

like image 343
eran Avatar asked May 07 '09 08:05

eran


People also ask

How do I reduce memory swap?

To clear the swap memory on your system, you simply need to cycle off the swap. This moves all data from swap memory back into RAM. It also means that you need to be sure you have the RAM to support this operation. An easy way to do this is to run 'free -m' to see what is being used in swap and in RAM.

What happens if swap space is full?

Thrashing can occur when total virtual memory, both RAM and swap space, become nearly full. The system spends so much time paging blocks of memory between swap space and RAM and back that little time is left for real work.

Should I disable swap memory?

To summarize:If memory pages cannot be swapped only when the server is idle, you should tune or disable swap.

How do I increase Windows swap space?

In the Performance section of the Advanced panel, click Settings to open the Performance Options window. Select the Advanced tab. In the Virtual Memory section, click Change to open the Virtual Memory window. Change the Maximum size to the value that is recommended in the bottom panel.


2 Answers

As you mentioned, forcing the app to stay in memory isn't the best way to share resources on the machine. A quick solution that you might find that works well is to simply schedule an event that wakes your service up at a specific time each morning before your clients start to use it. You can just schedule it in the windows task scheduler with a simple script or EXE call.

like image 85
Paul Alexander Avatar answered Nov 09 '22 15:11

Paul Alexander


I'm not saying you want to do this, or that it is best practice, but you may find it works well enough for you. It seems to match what you've asked for.

Summary: Touch every page in the process, on page at a time, on a regular basis.

What about a thread that runs in the background and wakes up once every N seconds. Each time the page wakes up, it attempts to read from address X. The attempt is protected with an exception handler in case you read a bad address. Then increment X by the size of a page.

There are 65536 pages in 4GB, 49152 pages in 3GB, 32768 pages in 2GB. Divide your idle time (overnight dead time) by how often you want (attempt) to hit each page.

BYTE *ptr;

ptr = NULL;
while(TRUE)
{
    __try
    {
        BYTE b;

        b = *ptr;
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        // ignore, some pages won't be accessible
    }

    ptr += sizeofVMPage;

    Sleep(N * 1000);
}

You can get the sizeOfVMPage value from the dwPageSize value in the returned result from GetSystemInfo().

Don't try to avoid the exception handler by using if (!IsBadReadPtr(ptr)) because other threads in the app may be modifying memory protections at the same time. If you get unstuck because of this it will almost impossible to identify why (it will most likely be a non-repeatable race condition), so don't waste time with it.

Of course, you'd want to turn this thread off during the day and only run it during your dead-time.

like image 40
Stephen Kellett Avatar answered Nov 09 '22 13:11

Stephen Kellett