在Windows中使用32位进程时遇到内存不足的问题,我开始使用性能监视器为该进程logging某些计数器。
虽然虚拟字节比私人字节和工作集都高是正常的,但是我发现在我的情况下有很大的差别,虚拟字节比私人字节和工作集都高。
什么特定的操作和Win32 / CRT函数(C或C ++)会增加虚拟字节,但不是私人字节和工作集?
我想这将是某种共享资源,如果我了解性能监视器中不同计数器的说明。
由于在不同版本的Windows以及不同的应用程序中使用内存计数器的命名约定在同一版本的Windows中似乎有一些(至less是说)混淆,所以我将下列内容放在一起:
根据MSDN – Windows发行版的内存限制,对于每个32位进程,32位Windows中的用户模式虚拟地址空间限制通常为2 GB。 IMAGE_FILE_LARGE_ADDRESS_AWARE
和4GT
可以达到3 GB。
以下是性能监视器中不同计数器的说明,以及MSDN(内存性能信息)中任务pipe理器中相应的列和包含信息的Win32结构。
虚拟字节是进程正在使用的虚拟地址空间的当前大小(以字节为单位)。 使用虚拟地址空间不一定意味着相应地使用磁盘或主内存页面。 虚拟空间是有限的,这个过程会限制它加载库的能力。
任务pipe理器XP:N / A
任务pipe理器Vista:N / A
结构: MEMORYSTATUSEX.ullTotalVirtual-MEMORYSTATUSEX.ullAvailVirtual
专用字节是当前的大小,以字节为单位,该进程分配的内存不能与其他进程共享。
任务pipe理器XP:VM大小
任务pipe理器Vista:提交大小
结构: PROCESS_MEMORY_COUNTERS_EX.PrivateUsage
工作集是此进程的工作集的当前大小(以字节为单位)。 工作集是进程中线程最近触及的一组内存页面。 如果计算机中的可用内存超过阈值,即使不在使用中,页面也会留在进程的工作集中。 当空闲内存低于阈值时,页面将从工作集中删除。 如果需要的话,在离开主存之前,他们将被软件故障切换回工作集。
任务pipe理器XP:内存使用情况
任务pipe理器Vista:工作集
结构: PROCESS_MEMORY_COUNTERS_EX.WorkingSetSize
(可能)增加虚拟字节而不增加私有字节的事情我现在可以想到:
二进制文件通常是共享的(即不是私有的),但是占用很大的地址空间。 这可能比二进制文件的大小还要大
使用VirtualAlloc来保留顺序地址空间而不必提交/访问它。 自定义内存管理器可能会这样做。
使用内存映射文件(不完全访问它)
通过使用VirtualAlloc,您可以分配虚拟地址空间,而无需实际分配任何物理内存。 这应该增加“虚拟字节”计数,但不是你的工作集大小。
内存不足可能是由于地址空间的运行造成的,因为预留了太多的地址空间。
你的编程语言是什么?
在托管框架中,私有字节表示由非托管资源分配的数据。 虚拟字节表示总内存使用量(非托管和管理数据)。
因此,在这样的框架中看到私有字节和虚拟字节之间的巨大差异是非常普遍的。