views:

352

answers:

4

I have a process that uses a lot of memory mapped files.
Problem is that those files are kept in physical memory, even when the machine is low on memory, and other processes require this memory.

I've tried using SetProcessWorkingSetSize to limit the process working set, but it doesn't help, the process' working set keeps growing over the max value.

Is there a better way to limit the process' working set?
Can I change Windows' heuristcs for paging memory mapped files?

A: 

Hi there.

I think this behaviour is due to how MMF (Memory Mapped Files) work. Have a look at this blog article. It explains that MMF files skip the Windows paging process, and thus are not backed by the page file. Instead, the MMF becomes the data backup in itself, which means, ultimately, it takes up more RAM since it's not being pages out (Er, I'm not sure I get that myself - best to read the blog!)

Here's the MSDN documentation for memory mapped files and here's another SO question relating to MMF.

Cheers. Jas.

Jason Evans
The MSDN article clearly shows that the MMF API is above the VMM, so it should be able to page to disk and clear unused pages.
Meidan Alon
+1  A: 

If you find that your process with the memory mapped files is holding on to a lot of those pages, then that means the OS has not needed to discard any of your memory mapped regions to give to other processes. So, how do you know other processes actually need the memory currently used for the mapped files? Just because the OS is low on physical RAM means nothing. Other processes have to demand memory to cause the OS to drop your mapped pages and give RAM to them.

So, it appears that your mmap-I/O process is starving your other process which uses RAM less frequently. One approach is to judiciously lock memory in the process that is being starved. Look at VirtualLock for win32.

karunski
I know it because I own the other process too, I see it has a lot of page faults and doesn't use as much memory as it requires.
Meidan Alon
But how is performance affected? A page fault can be very cheap when the OS doesn't have to commit dirty pages to disk. If your other processes is using less memory than you think then clearly it doesn't actually require it.
karunski
I should've mentioned it, performance (of the other process) is a few orders of magnitude slower.
Meidan Alon
OK, your I/O access pattern is causing the virtual memory manager to starve your other process. Answer edited.
karunski
The mmf-process hasn't accessed its memory for a few minutes before I started the other process, could it still be a starvation scenario?
Meidan Alon
Yes probably. If no other process demands the memory there is no reason for the OS to discard it from RAM.
karunski
A: 

Hi! Check my answer here; with VirtualUnlock() you can manually uncommit portions of the MMFs; e.g., sections you don't think you'll be accessing again soon.

Guillermo Prandi
A: 

Ended up using brute force VirtualUnlock.

PROCESS_MEMORY_COUNTERS pmc;
if (GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) )
{
        if (pmc.WorkingSetSize > MaxWorkingSetSize)
        {
                VirtualUnlock(FilePtr.pData, MaxWorkingSetSize);
                UnmapViewOfFile(FilePtr.pData);
                CloseHandle(FilePtr.hFileMap);
                CloseHandle(FilePtr.hFile);
        }
}
Meidan Alon