当Windows可以访问的总内存也限制在4GB时,它如何为多个进程分别提供4GB的地址空间



Windows如何为多个进程分别提供4GB地址空间当它可以访问的总内存也被限制为4GB时。

我在Windows内存管理中找到的上述问题的解决方案(撰稿人:Pankaj Garg)

解决方案:

要实现这一点,Windows使用x86处理器(386和以上),称为寻呼。分页允许软件使用不同的内存地址(称为逻辑地址)而不是物理内存住址处理器的分页单元将此逻辑地址转换为物理地址是透明的。这允许系统具有自己的4GB逻辑地址空间。

有人能帮助我以更简单的形式理解它吗?

基本思想是物理RAM有限。一旦它装满了,你就开始把东西存储在硬盘上。当进程请求当前磁盘上的数据或请求新内存时,您可以通过将页面转移到磁盘来从RAM中弹出页面,然后在实际需要的数据中分页。

操作系统维护一个称为页表的数据结构,以跟踪哪些逻辑地址与当前物理内存中的数据相对应,以及磁盘上的内容在哪里。

每个进程都有自己的虚拟地址空间,并使用该空间中的逻辑地址进行操作。操作系统负责将对给定进程和逻辑地址的请求转换为磁盘上的物理地址/位置。它还负责防止进程访问属于其他进程的内存。

当进程请求当前不在物理内存中的数据时,会触发页面故障。发生这种情况时,操作系统会选择一个页面移动到磁盘(如果物理内存已满)。有几种页面替换算法用于选择要踢出的页面。

最初错误的假设是"当它可以访问的总内存也限制在4GB时"。这是不真实的,操作系统可以访问的内存总量并没有那么有限。

32位代码可以访问的32位地址有限制。它是(1<<32),它是4GB。然而,这只是同时访问的数量。想象一下操作系统有卡A,B。。。,F和应用程序一次只能访问四个。App1可能正在看到ABCD、App2-ABEF、App3-ABCF。应用程序看到4,但操作系统管理6。

对32位平面内存模型的限制并不意味着整个操作系统都受到相同的限制。

Windows使用一种称为虚拟内存的技术。每个进程都有自己的内存。这样做的原因之一是出于安全原因,禁止访问其他进程的内存。

正如您所指出的,分配的虚拟内存可能比实际物理内存大。这就是分页过程的作用所在。我对内存管理和微体系结构的了解有点生疏,所以我不想发表任何错误的文章,但我建议阅读http://en.wikipedia.org/wiki/Virtual_memory

如果你对更多的文献感兴趣,我建议你阅读《结构化计算机组织——Tannenbaum》

虚拟地址空间不是RAM。这是一个地址空间。每个page(页面的大小取决于系统)都可以取消映射(页面不在任何地方,也不可访问。它不存在)、映射到文件(页面不可直接访问,其内容存储在磁盘上)、映射至RAM(这是您可以实际访问的页面)。

映射到RAM的页面可以进行交换或固定。固定的页面永远不会交换到磁盘。可交换页与光盘上的某个区域相关联,可以写入该区域以释放它们正在使用的RAM。

映射到RAM的页面也可以是只读、只读、读写。如果它们是可写的,则可以直接写或写时复制。

多个页面(既在同一地址空间内又在不同的地址空间之间)可以被相同地映射。这就是两个独立的进程如何访问内存中的相同数据(可能发生在每个进程的不同地址)。

在现代操作系统中,每个进程都有自己的地址空间。在32位操作系统上,每个进程都有4GiB的地址空间。在64位操作系统上,32位进程仍然只有4GiB(4千兆二进制字节)的地址空间,但64位进程可能有更多的地址空间。一般来说,它们有18个EiB(18个十六进制字节,即18874368个TiB)。

地址空间的大小完全独立于RAM存储器的数量和实际分配的空间的数量。在一台具有1GB RAM的机器上,可以有100个进程,每个进程具有18EiB的地址空间。事实上,从典型的机器只有几兆字节或RAM的时候起,windows就一直为每个进程提供4GiB的地址空间。

假设上下文是32位系统:

除了http://en.wikipedia.org/wiki/Virtual_memory然而,内核给每个进程的内存抽象是4GB,一个进程实际上可以使用远小于4GB的内存,因为在每个进程中,内核也映射在进程的大多数页面中。一般来说,在4GB之外的NT系统中,2GB由内核使用,而在*nix系统中,1GB则由内核使用。

我很久以前在用Windows作为案例研究的操作系统课程中读过这篇文章。我给出的数字可能不准确,但它们可以让你对幕后发生的事情有一个很好的了解。据我所知:

在windows中,使用的内存模型是按需分页。在英特尔上,页面大小为4k。最初,当你运行一个程序时,每个4K只加载4页。这意味着总共分配了16k的存储器。程序可能更大,但不需要一次将整个程序加载到内存中。其中一些页面是数据页面,即变量和数据结构所在的可读/写页面。而另一个是包含可执行代码即代码段的代码页。IP被设置为代码段的第一条指令,程序在分配了4GB的情况下开始执行。

当需要更多的页面时,即您请求更多的内存(数据段)或您的程序进一步执行并需要其他可执行指令(代码段)时,Windows会检查是否有足够的内存可用。如果是,则加载这些页面并将其映射到进程的地址空间中。如果可用内存不多,那么windows会检查哪些页面已经有很长一段时间没有使用了(这是为所有进程运行的,而不仅仅是调用进程)。当它找到这样的页面时,它将它们移动到分页文件以释放内存中的空间,并加载请求的页面。

如果有时你的程序从已经加载的dll中调用代码,windows只需将这些页面映射到进程的地址空间中。不需要再次加载这些页面,因为它们在存储器中已经可用。从而避免了重复并节省了空间。

因此,理论上,进程使用的内存比可用内存多,它们可以使用4GB的内存,但实际上一次只加载进程的一部分。

(如果你觉得我的答案有用,请标记它)

相关内容

最新更新