Windows内存之任务管理器

最近在看内存方面的知识,打算写一系列的博客分享记录一下。

本篇博客先介绍一下虚拟内存和物理内存,以及虚拟内存地址空间和物理内存地址空间的概念。然后介绍一下任务管理器里各个内存的含义。

目录

1.物理内存  vs 虚拟内存

2.虚拟内存地址空间 vs 物理内存地址空间

虚拟内存地址

物理内存地址

系统内存管理的分页机制和调度机制

3.任务管理器中的内存信息

1.工作集Working Set(内存) = 内存(专用工作集)+ 内存(共享工作集)

2.提交大小Comitted Memory

3.内存的独占性


1.物理内存  vs 虚拟内存

物理内存就是内存条,实实在在的内存,即RAM。

而虚拟内存其实就是内存管理中的一个概念。

对于一个进程来说,虚拟内存是进程运行时所有内存空间的总和。但这所有内存空间可能有一部分不在物理内存中,另外一部分在其他介质中,比如硬盘。

举个例子,当你的程序需要创建一个1G的数据区,但是此时剩余500M的可用物理内存了,那么此时势必不是所有数据都能一起加载到内存(物理内存)中,势必有一部分数据要放到其他介质中(比如硬盘),待进程需要访问那部分在其他介质中的数据时,再通过调度进入物理内存。

2.虚拟内存地址空间 vs 物理内存地址空间

虚拟内存地址

虚拟内存地址的大小与cpu地址总线位数相关,因为CPU的地址线多少决定了可以直接进行寻址的内存空间大小。

所以32位的CPU,它的地址总线是32位的,也就是它可以寻址0~0xFFFFFFFF(4G)的地址空间。(所以32位系统,最大就是支持4GB物理内存。)

但是现在的系统一般都是64位的了,理论上64位的CPU就可以支持最大16EB的内存空间。(ps:K->M->G->T->P->E)

物理内存地址

物理内存地址的大小和物理内存条的容量相关。

比如16G的内存条,它可以寻址0~0x3FFFFFFFF(16G)的地址空间。

系统内存管理的分页机制和调度机制

32位地址会对虚拟内存地址空间(32位为4G)产生每一页为2^12 = 4K大小的页,一共有1M个的

物理内存地址空间产生同样大小为4K的,称之为页帧。32位地址,内存是2G的话,一个有500K个页帧

而操作系统维护着一个页表,这个映射表记录着页号页帧号的 对应关系。

从上面可以看出,虚拟内存页的个数  是大于  物理内存页帧的个数。那势必会有一些虚拟内存页的地址 没有对应的物理内存地址空间。如果当前已经没有可用的页帧的话,操作系统会找到一个最少使用的页帧,先让他失效(称为页面失效page fault 功能),并把它写入磁盘,随后把需要访问的页放到此页帧中,并修改页表中的映射,这样就保证所有的页都有被调度的可能了。这就是处理虚拟内存地址到物理内存的步骤,

那么上述中的写入磁盘指的是什么呢?在硬盘上有个分页文件,叫pagefile.sys文件,一般在硬盘的操作系统所在的分区中。那么如何设置可以写入硬盘的内存大小呢——我的电脑 右键 选择【属性】,左侧栏里选择【高级系统设置】,然后点击如下图所示:正如解释的是,操作系统把这个分页文件当作RAM使用,即硬盘中的虚拟内存的概念。

3.任务管理器中的内存信息

打开任务管理--详细信息---右键 选择列,选择下面这4个。

1.工作集Working Set(内存) = 内存(专用工作集)+ 内存(共享工作集)

工作集表示进程此时所占用的总物理内存(即占用RAM内存)。这个值是由两部分组成专用工作集 加 共享工作集。其中 专用工作集内存 是此进程独占的物理内存,共享工作集内存是指这个进程与其它进程共享的内存,比如加载一个dll所占用的内存。

2.提交大小Comitted Memory

是程序独占的内存。这个值也是包含两部分,一部分是独占的理内存(即专用工作集内存),另一部分是分页文件中的独占内存映射。分页文件即上述介绍的硬盘中的虚拟内存,当RAM物理内存资源紧张,或者有数据长时间未使用时,操作系统通常会将数据占用的物理内存先映射到页面文件(pagefile.sys)中,并拷贝数据到硬盘中,然后将本来占用的RAM空间(页帧号)释放。这个即位虚拟内存技术。

下面是一个Windows API,功能是向操作系统发送请求, 将此进程的不常用的内容从物理内存中换出到分页文件中保存

EmptyWorkingSet

3.内存的独占性

来自 https://www.bbsmax.com/A/KE5QEZYL5L/

下面通过一个网上的例子分析一下代码中那些内存是独占的,那些内存是共享的。

 有如下的main.exe,代码如下:(定义了一个5M的全局变量,一个5M的常量,并申请了一个5M的内存。程序代码本身大小为2M。)

char g_str[5*1024*1024];
const char STR[5*1024*1024];
void main()
{
    char *p = (char*) HeapAlloc(GetProcessHeap(), 0, 1024*1024*5);
    call_lib();
}

lib.dll的代码如下:(定义了一个4M的全局变量,一个4M的常量,并申请了一个4M的内存。程序代码本身大小为1M。)

char g_str[4*1024*1024];
const char STR[4*1024*1024];
void call_lib()
{
    char *p = (char*) HeapAlloc(GetProcessHeap(), 0, 1024*1024*4);
}

其中:

1.全局变量是进程独占的,别的进程不可以共享,因为不同的进程的全局变量的值可能是不一样的。

2.常量共享的,常量是放在常量区的,所有进程的常量值都是一样的。

3.alloc出来的内存与全局变量类似,也是进程独占的。

4.程序代码是共享,可以由不同进程共享,并且不会发生改变。

所以main.exe的占用的总内存为:

Virtual Size = 5M的全局变量 + 5M的常量 + 5M的内存 + 2M的程序代码+ 4M的全局变量 + 4M的常量 + 4M的内存 + 1M的程序代码= 30M.

main.exe独占的内存:

Private Bytes = 5M的全局变量 + 5M的内存+ 4M的常量 + 4M的内存=18M.

猜你喜欢

转载自blog.csdn.net/u012138730/article/details/90055485