Why does my page table take up so much memory?

My 64-bit Windows 7 PC is very sluggish. I noticed in Task Manager that my memory usage is near 100% - however the usage reported for each process does not add up to the total 6GB (Firefox shows about 500MB, the rest much less). I downloaded RAMMap and found that the Page Table is taking up a considerable amount of memory (2.5GB).

RAMMap screenshot

I googled this and got nowhere - apparently the page table can get fragmented. Obviously I will reboot the machine and see if that helps. But is there a better way to fix it?

EDIT: rebooted, and the page table is down to 30MB.

EDIT 2: After a few days of uptime, page table use is creeping up again. I followed @magicandre1981's instructions in this answer to find the source of the page table usage. Unfortunately I drew a blank - the page table is used by "Unknown"!

WPA screenshot

Anyone got any bright ideas?


Solution 1:

I need to comment to the comments to the question, particularly the confusion between "page table" and "page file". This is not an answer but it won't fit in the space allowed for comments.

"Page table" is indeed a very different thing from the pagefile. Having n MB of RAM used for page tables does not mean you are using n MB of pagefile space. And although some page table entries (PTEs, which are what page tables consist of) do refer to pagefile contents, not all do.

The page tables are in-memory structures that are used by the CPU's MMU to perform address translation from virtual addresses (again, not the pagefile) to physical addresses, and by the OS to keep track of virtual address space and help resolve page faults. Page tables consist of page table entries (PTEs). Each PTE occupies 8 bytes and defines 4K bytes of virtual address space - i.e. one virtual page. There is, roughly, one PTE for each not-free page of virtual address space.

By the way, although the pagefile can experience both external and internal fragmentation (the former is usually not much of a problem; the latter can be ameliorated by making it about four times as big as it needs to be), page tables cannot. They're sort of always fragmented already, and it doesn't matter in the slightest.

Each PTE has a "valid" bit. For "valid", aka "resident" pages, the PTE contains the physical page number that corresponds to the virtual page number that's associated with the PTE; this is used directly by the MMU.

For "invalid" pages the MMU raises a page fault and the PTE then has many possible formats and interpretations.

Note: All of the above applies to any operating system that enables paging on x86/x64. The following is largely specific to Windows, but many of the concepts apply to other OSs, with differences in details of implementation.

For a page in the page cache, the PTE still contains the physical page number. For pages that have been lost from RAM and written to the pagefile, the PTE does contain the pagefile number and the offset within the pagefile where the page contents were written. Other possible PTE contents are references to virtual address descriptors, references to "prototype PTEs", references to demand zero pages, etc., which I'm not going to get into. Suffice it to say that only some of the PTEs refer to locations in pagefiles.

I mention all of this mostly to show that the pagefile and the page tables, while related, are definitely not the same thing.

Page tables are organized into a tree structure. There is a different such tree, or collection of page tables, for each process - this is what allows each process to define its own instance of virtual address space. The page table at the root of the tree must be in RAM at all times. The others are pageable; they are even non-existent where they would correspond to large (minimum of 2 MB) regions of undefined, or free, virtual address space.

The page table entries in the tables at the "leaves" of the tree correspond to pages of virtual address space. The PTEs in the higher-level tables - the ones closer to the root (and the root itself) - tell where the next lower-level tables are (if they exist at all).

The number shown by RAMmap is the physical memory (RAM) occupied by all of the resident (in-RAM) page tables for all processes plus the OS.

What is important here is that the system in the OQ had 2.5 GB of RAM tied up with page tables. That means that, at minimum, there's 2.5 GB of page tables defined. Since page tables are themselves pageable, the virtual size could be much larger than the physical size, which is all RAMmap can show us. But assume it's "only" 2.5 GB. At eight bytes per PTE that is about 320 million PTEs. Since each PTE defines one page - 4K bytes - of virtual address space, that means that over 1.2 terabytes of virtual address space are defined by in-memory page tables.

That's not impossible but it's rather a lot.

For reference, on my system atm, I have about 125 MB of RAM in page tables. This would indicate only about 65 GB of virtual address space. My actual virtual usage is much higher (125 TB just for processes) but that is because most of the page tables aren't in RAM. "Large pages", another thing I shouldn't get into here, can also help account for different ratios between size of page tables vs. size of in-use virtual address space.

So: TO find the culprit, I would first go looking in Performance Monitor under the Process category for processes with a high "Virtual Bytes" counter value.

Solution 2:

Open the "Processes" tab in RamMap and sort by name. Look for a suspiciously high number of the same process. On my machine, "SynTPEnh.exe" was the culprit (a part of the touchpad driver). After a week of uptime, it amassed tens of thousands of entries in the page table, each 32kb in size.

My page table size was 1 GB, after a reboot, it's only 50 MB.

enter image description here

Solution 3:

Lenovo "RapidBoot Shield" was the culprit for me.

After a week without a reboot my "Page Table" was using 4GB+. It turned out that every terminated process stuck around using 20K RAM (4K private, 16K Page Table) as shown in the "Processes" tab of RamMap, and there were ~200,000 of them!

Rebooting reduced the list but it started growing again. It was reproducible by opening notepad, killing it and observing that it is stays in the RamMap processes list.

Based on suggestions on this technet thread I uninstalled "RapidBoot Sheild", rebooted the machine and then processes no longer stayed around when killed. Problem solved!

Solution 4:

In my case these were Aksdf.sys and Hardlock.sys filter driver from Aladdin Knowledge Systems Aladdin drivers. I have managed to find that answer using RAMMap also. It displayed the memory, consumed by terminated process. The processes were removed from the Windows process list yet persisted in the memory map. The drivers seem to prevent complete termination of the processes.

Solution 5:

I asked my IT department about this, and they were similarly bamboozled. I ended up using DriverEasy to update my drivers. The ones that seemed to make the difference, strangely enough, were the monitor drivers. Previously I'd had the standard Windows "Generic PnP Monitor" drivers. But when I updated those to the correct make and model of my monitors, the issue seemed to go away.