在Performance monitor中可以通过private bytes和Virtual bytes来衡量程序的内存使用. 在task manager中, 也有Memory Usage和VM Size两项. 但是仔细比较后会发现Memory Usage并不是对应private bytes, VM Size也不是对应Virtual Bytes.


其实, task manager中的Memory Usage对应的是working set, VM Size对应的是private bytes. 因此如果使用task manager观察内存使用, 应该注意到这个差别.


Working Set和Private Bytes

==============

一个有趣的问题是, working set指目前程序所消耗的物理内存, private bytes指的是commit的内存, 那么为什么有些进程的working set比private bytes还大? 要回答这个问题, 需要仔细看看两者的定义:


  • "Working Set refers to the numbers of pages of virtual memory committed to a given process, both shared and private."
  • "Private Bytes is the current size, in bytes, of memory that this process has allocated that cannot be shared with other processes."

所以, Working Set包含了可能被其他程序共享的内存, 而Private Bytes只包括被当前进程使用的内存.


DLL是一个典型的可能被其他程序共享的资源. DLL的加载使用文件映像, 因此包含DLL的物理内存可以被同时映像到多个进程上. 所以在进程中加载DLL的内存只能算到working set上, 而不能被算到private bytes上.


在解决内存问题的时候Shared的部分一般可以不用考虑.

一个进程使用内存的时候, 它占用的内存会被分为两部分, 一部分是working set, 另一部分是private byte减去working set. 其中working set是贮存在物理内存中的, 而剩下的另一部分是paging file, 存在磁盘上.


一般来说把所有进程的working set加起来会比你机器上所拥有的物理内存要大, 这是因为有Shared的资源(比如DLL)的缘故.


TechNet上的定义

==============

Working Set

The set of memory pages (areas of memory allocated to a process) recently used by the threads in a process. If available memory on the server is above a specified threshold, pages remain in the Working Set of a process even if they are not in use. When available memory falls below a specified threshold, pages are removed from the Working Set. If these pages are needed, they will be returned back to the Working Set before they leave main memory and are made available for other processes to use.

Private Bytes

Displays the current number of bytes this process has allocated that cannot be shared with other processes.

Virtual Bytes.

The current size, in bytes, of the virtual address space for this process. The virtual address space limit of a user mode process is 2 GB, unless 3 GB address space is enabled by using the /3GB switch in boot.ini.


Working Set, Virtual Bytes, 和Private Byte的更多信息

==============

原文:

Private Bytes refer to the amount of physical memory (RAM) that the process executable has asked for - not necessarily the amount it is actually using. Private bytes are "private" because they (usually) exclude memory-mapped files (i.e. shared DLLs). But - here's the catch - they don't necessarily exclude memory allocated by those files. So if your executable depends on any libraries - and almost every executable does - you cannot always tell whether a change in private bytes was due to the executable itself or some library it links to. Also note that "physical memory" is not a perfect description - what it really means is bytes that can be addressed without a page fault.

翻译:

Private Bytes指的是进程可执行程序已经索要了的物理内存的量, 不一定是它实际正在使用的内存量. Private Bytes之所以是"private"的, 是因为它通常不包括内存映射文件(memory-mapped file), 比如说共享的DLL. 但是, 有一点要注意, 虽然private bytes不包括共享的DLL本身, 但是会包括由那些共享的DLL所分配的内存. 所以, 如果你的可执行文件依赖于任何的dll库(其实几乎所有的可执行程序都要依赖于dll库), 你就不能明确private byte的一个变动是由可执行程序自己引发的, 还是由DLL分配的. 还有, 注意, "物理内存"其实并不是对private bytes的一个完美的描述, 物理内存的真实的意义是: 无需page fault就可以寻址到的内存.


原文:

Working Set refers to the total physical address space used by the process. This includes memory-mapped files and quite possibly several other things; a 32-bit process can access 4 GB of address space and not all of that address space is actually memory. This is the same value that gets reported in Task Manager's "Mem Usage" and has been the source of endless amounts of confusion in recent years. Similarly to private bytes, this is "physical" in the sense that it can be addressed without a page fault.

翻译:

working set的意思是被进程使用的全部物理内存地址空间. 这包括内存映射文件, 还有些其他的东西. 一个32位的进程可以寻址4GB的地址空间, 而且这4G并不都在实际的内存中. 跟private bytes相似, working set描述中的physical的意思也是无需page fault即可寻址.


原文:

Virtual Bytes are the total virtual address space occupied by the entire process, including memory-mapped files such as shared DLLs. This is like the working set except it includes data that has already been paged out and is sitting in a pagefile somewhere. The total virtual bytes used by every process on a system under heavy load will add up to significantly more memory than the machine actually has.

翻译:

Virtual Byte是整个进程占用的全部虚拟地址空间, 包括诸如共享dll在内的内存映射文件. 它跟working set很像, 不一样的是, 它还得算上已经被page out的存放在别的什么地方的pagefile中的数据. 一个高负荷系统中所有进程的全部的virtual bytes加起来, 会比机器实际拥有的内存多很多.


个人理解

===============

假设我有一台机器, 机器有物理内存1024M. 机器上面仅运行着三个进程A, B, C.

下面的情况是可能的:

A和B仅共用一个叫做common.dll的库文件. common.dll为A分配了10M的内存, 为B分配了20M内存.

common.dll本身占30M内存.

A的可执行程序以及其数据本身占用了40M, B的使用了50M, C的使用了60兆.

A的可执行程序本身使用的内存中有5兆不在内存中, 在pagefile中.

A没有引用其他的dll文件.


那么A的private bytes是40-5+10 = 45M

A的working set是40-5+30 = 65M

A的virtual bytes是40+30+10=80M