Question regarding total commit charge calculation


Recently I’ve run into an interesting, if not frustrating, issue related to
the way the total commit charge of a machine is calculated. My
understanding of the algorithm is at a conceptual level only, so I apologize
in advance if there are flaws in my understanding (and please correct me if
so). With that said, the way that the total commit charge of a machine is
calculated seems to be by adding the values of the CommitCharge associated
with each process together (and by adding other non-process sources of
committed pages as well).

The problem that I’ve run into is related to the fact that committed pages
associated with views of sections seem to also be included in this
calculation. When a view of a file-backed section is mapped into a process
it appears that the majority of the pages are not committed and instead
paged in on demand or managed by the cache manager. The opposite is true
for pagefile-backed sections, as one would expect, considering all of the
pages associated with the section are committed to memory due to them being
allocated from the pagefile. Herein lies the problem. When a view of the
pagefile-backed section is mapped the total commit charge of the process
that is being mapped into increases by the number of pages associated with
the pagefile-backed section.

As an example, if one were to map a view of a pagefile-backed section that
is 200 pages in size into every running process (let’s say 10 processes),
the total commit charge of the machine would end up increasing by 2000
pages! Even though the physical pages that the views are mapped against are
shared, the commit charge still increases. I believe I understand why the
commit charge is increasing, as it seems obvious that the algorithm for
calculating a process’ commit charge is roughly equivalent to enumerating
the VADs in a process and adding the u.VadFlags.CommitCharge of each VAD
together to produce the total CommitCharge of a process. The part that does
not make sense to me is why the pagefile would need to grow under conditions
where the total commit charge of the machine has been drastically increased
by having large views of pagefile-backed sections mapped into a number of
processes. This leads to Windows thinking it’s low on memory as well as the
general user misconception that the machine is actually low on memory (even
though it clearly should not be, and the amount of free physical memory
reflects this).

So, to summarize my questions:

  1. What is the logic behind including the total number of committed pages
    associated with a pagefile-backed section in a process’ total CommitCharge
    aside from the obvious fact that the pages are indeed committed?
  2. Why does the pagefile need to grow simply because the total commit charge
    for the machine reaches the defined commit charge limit even if the majority
    of committed pages are backed against a single set of physical pages (as is
    the case with pagefile-backed sections)? At a guess, is it in some way
    related to the need to support complete memory dumps by making the pagefile
    large enough to hold all committed pages? If so, is this the only reason?