操作系统中的虚拟内存

时间:2018-03-10 16:01:17

标签: virtual-memory

我一直在努力了解正在运行的程序使用的虚拟地址空间概念。让我使用在32位Windows操作系统上运行的32位应用程序的示例。

据我所知,每个进程都认为(或“认为”)自己是系统上运行的唯一应用程序(这是正确的吗?)并且它可以访问4GB地址,其中标准配置为2 GB分配给内核,2分配给用户进程。我对此有以下问题:

  1. 为什么用户进程需要在其地址空间中加载内核代码?为什么内核不能拥有自己的完整4 GB地址空间,以便每个进程可以享受4GB空间?

  2. 在2GB + 2GB配置中,2GB是否足以让内核加载其所有代码?当然构成内核的所有应用程序代码都是(或可能)超过2GB?类似地,当您考虑自己的代码以及其他依赖项(例如dll)时,分配2GB地址空间的用户进程肯定需要超过2 GB?

  3. 我对此主题的另一个问题是关于计算机系统上存在正在运行的进程的各个位置 - 例如,我有一个程序C:\ Program Files \ MyApp \ app.exe。当我启动它时,它使用虚拟地址空间加载到进程中,并使用paging(pagefile.sys)来使用有限的RAM。我的问题是,一旦app.exe启动,它是完全加载到RAM +页面文件还是只从C:\ Program Files \ MyApp \ myapp.exe加载一部分程序,因此它继续引用exe位置需要更多时间吗?

  4. 最后一个问题 - 在32位操作系统上,如果我有超过4 GB的RAM,内存管理是否可以使用超过4 GB的RAM空间,或者它会浪费?

  5. 由于 史蒂夫

2 个答案:

答案 0 :(得分:1)

  

为什么用户进程需要在其地址中加载内核代码   空间?为什么内核不能拥有自己的完整4 GB地址空间   每个进程可以享受4GB空间吗?

一个过程可以有一点点(小一点点)4 GiB。问题是将虚拟地址转换为物理地址是很昂贵的,因此CPU使用"转换后备缓冲区" (TLB)加快速度;并且(至少在较旧的CPU上)更改虚拟地址空间(例如,因为内核在其自己的虚拟地址空间中)导致TLB条目被丢弃,这导致(虚拟)存储器访问变慢(因为" TLB错过")。将内核映射到所有虚拟地址空间可避免/避免此性能问题。

注意:对于带有" PCID"的现代CPU通过为每个虚拟地址空间提供一个ID,可以避免性能问题;但是大多数操作系统都是在此功能存在之前设计的,所以(即使有熔化补丁)它们仍然以相同的方式使用虚拟地址空间。

  

在2GB + 2GB配置中,2GB足以让内核加载所有内容   码?当然,构成内核的所有应用程序代码都是更多   超过2GB?类似地,分配2GB地址的用户进程   当你考虑自己的代码时,空间肯定需要2 GB以上   以及其他依赖项,如dlls?

代码永远不是问题 - 它的数据。通常,大多数软件要么不需要2 GiB的空间,要么需要超过4 GiB的空间;并且很少需要2 GiB但不需要超过4 GiB。对于需要超过4 GiB空间的东西,大约10年前所有东西都转移到了64位(通常是131072 GiB或更多的#34;用户空间")所以......

  

我的问题是,一旦app.exe启动,它会完全加载到RAM + Pagefile中,或者它只从C:\ Program Files \ MyApp \ myapp.exe加载一部分程序,因此它继续在需要时更多地参考exe位置?​​

大多数现代操作系统使用"内存映射文件"。我们的想法是,可执行文件最初根本不会加载到RAM中,但是如果/当页面中的某些内容实际上被访问时,第一次它会导致页面错误"页面错误处理程序从磁盘中获取页面。这往往会减少RAM消耗(永远不会从磁盘加载的东西)并改善进程启动时间。

  

在32位操作系统上如果我有超过4 GB的RAM,内存管理是否可以使用超过4 GB的RAM空间,或者它会浪费?

有多个虚拟地址空间,其中虚拟地址可能是32位宽,并且单个物理地址空间(取决于CPU支持的扩展)物理地址可能是36位宽(甚至更宽)。这意味着您可以在32位操作系统上运行32位操作系统" CPU可以有效地使用最多(例如)64 GiB的RAM(如果你能找到真正支持它的主板)。在这种情况下,CPU仍然将虚拟地址转换为物理地址,并且进程不需要知道物理地址大小;但是单个进程本身无法使用所有RAM(您需要很多进程才能使用所有RAM)。

答案 1 :(得分:1)

  

为什么用户进程需要在其地址空间中加载内核代码?为什么内核不能拥有自己的完整4 GB地址空间,以便每个进程可以享受4GB空间?

通常没有内核进程(NULL进程除外)。大多数CPU在当前正在运行的进程的上下文中处理异常和中断。为了支持这一点,内核需要位于同一位置并且在所有进程中具有相同的布局。否则,在一个进程中发生的中断将与另一个进程正在运行时发生的中断处理不同。

  

在2GB + 2GB配置中,2GB是否足以让内核加载其所有代码?当然构成内核的所有应用程序代码都是(或可能)超过2GB?类似地,当您考虑自己的代码以及其他依赖项(例如dll)时,分配2GB地址空间的用户进程肯定需要超过2 GB?

你有误解。内核空间中没有应用程序代码。内核空间代码仅在响应中断或异常时执行。

对于我见过的任何内核来说,2GB就足够了。事实上,一些32位系统(硬件允许它)使内核空间小于2GB,并相应地增加了用户空间的大小。

  

我对此主题的另一个问题是关于计算机系统上存在正在运行的进程的各个位置 - 例如,我有一个程序C:\ Program Files \ MyApp \ app.exe。当我启动它时,它使用虚拟地址空间加载到进程中,并使用paging(pagefile.sys)来使用有限的RAM。我的问题是,一旦app.exe启动,它是完全加载到RAM +页面文件还是只从C:\ Program Files \ MyApp \ myapp.exe加载一部分程序,因此它继续引用exe位置在需要时更多?

这取决于系统。在任何合理设计的系统上,将分配辅助存储以支持进程用户地址空间中的每个有效页面。 "其中"取决于系统。例如,某些系统使用可执行文件作为代码和静态数据的页面文件。只有可写数据才会进入页面文件。但是,一些原始操作系统不支持以这种方式直接对文件进行分页。

  

最后一个问题 - 在32位操作系统上,如果我有超过4 GB的内存,内存管理是否可以使用超过4 GB的RAM空间,或者它会浪费?

这取决于系统。 32位操作系统可以使用超过4GB的RAM。每个进程限制为4GB,但各种进程可以使用超过4GB的物理内存。

让我们说你有4K页面。那个12位。理论上,32位处理器可以具有64位页表条目。在这种情况下,处理器可以轻松访问超过4GB的物理内存。

更常见的情况是32位处理器具有32位页表条目。理论上,具有4K页面的32位页表可以访问2 ^(32 + 12)字节的内存。实际上,页表条目中的一些32位必须用于系统目的。如果控制位少于12个,则处理器可以使用超过4GB的物理内存。