我对有关虚拟内存的一些主题感到困惑。所以,我将逐点列出并提出问题。回答我会更喜欢,如果你也列出一些我可以清除怀疑的来源。我将参考一个linux elf可执行文件来讨论。
我听说每个进程在32位系统中都有4gb的地址空间。当我检查我的可执行可重定位文件之一的objdump时,我看到它有从00000000到ffffffff的限制。它还包含内核空间。这是文件的地址空间。 这是我们谈论的虚拟内存吗?如果是,那么我已经读过虚拟内存机制允许运行非常大的进程并且进程大小不受主内存大小的限制(我们可以带来所需在需求 - 请求分页时,页面到主存储器)。 那么如果虚拟内存只有4gb,是不是将程序的最大大小限制为4gb?另外,我检查了另一个文件的objdump并且它具有相同的地址(即00000000到ffffffff)。 那么,这是什么意思?这是否意味着我们的文件是某种可重新定位的文件,将再次添加起始地址(尽管这看起来很荒谬,因为它已经是可执行的可重定位目标文件)。
我已经读过,在已经实现分段的内存中,cpu产生虚拟(逻辑)地址。该地址有三个部分 - 段,段内的偏移量。此外,这里讨论的部分是代码,数据,堆栈等。
在流程地址空间中,这些段位于特定位置。那么,cpu的虚拟地址的内容是什么? 生成的虚拟地址是否范围从00000000到ffffffff?如果是,则是访问虚拟地址内容的过程,具体如下: -
The segment part is looked up in the segment descriptor table to find the segment's
starting address in linear address space. Then the offset is indexed within the segment and
the resulting address is the linear address. Then, we look up the page table and map the
address to physical address. If the page is not currently in the main memory, it is
brought.
这再次出现了这样一个事实:任何时候都没有进程可以完全进入主内存,因为整个内存只会占用一个进程(因为进程的地址空间本身就是4gb) )。
此外,如果所有进程都有从00000000到ffffffff的地址空间,并且一次可以在主内存中存在多个进程,那么所有进程都应该有自己的段描述符表,该表返回段中的段地址线性地址空间
答案 0 :(得分:2)
这是一个非常开放的问题,对不同的术语有许多混淆的用法。我将尝试尽可能多地解决您的问题,并提供一些可能有用的其他有用信息。
“我听说过每个进程在32位系统中都有4gb的地址空间。”不完全正确。每个进程在32位系统中具有3.2GB的最大可寻址空间。这并不意味着这个内存曾经被分配过,而且一旦进程启动它肯定不会被分配。 “这是我们谈论的虚拟记忆吗?”不。虚拟内存与进程的可寻址空间无关。稍后会详细介绍。
这个问题没有多大意义,我将在下面解释。但值得注意的是,多个进程一次 完全适合内存,因为进程不会自动分配其完整的可用内存。 (如果文本编辑器在打开后立即分配4GB内存,那么它就不是一个流行的文本编辑器!)
我不是专家,但我非常怀疑每个程序在运行时都有自己的内核代码副本。仅安全性和性能问题使这成为一种非常不可能的解决方案。
现在,一些可能对您有所帮助的定义。
00000000
到fffffff
范围是流程可用的逻辑范围,这是在流程中用于引用内存的地址。内核会将此转换为物理地址,该地址在实际执行代码时由CPU使用,基于进程内存的物理偏移(和分段)。该物理位置可以位于可用存储空间中的任何位置,并且如果应用程序被分页并且在其中,则物理位置可以在应用的生命周期期间改变。但是,应用程序本身只需要引用自己的逻辑地址空间。术语“逻辑”与“物理”地址用于突出显示地址不是真实的地址,而是相对于相关内存子集的地址 - 即对于进程'自己的地址记忆空间。我不是这方面的专家,但我希望这有助于澄清你的一些问题。