为每个进程提供地址空间有什么好处?

为每个进程提供地址空间有什么好处?

我知道最基本的好处是提供一个抽象层,它允许进程不必担心其虚拟内存应该如何物理分配,而这由操作系统来处理。然而,除此之外,我们还能期待这样做的哪些优点/缺点呢?

答案1

每个进程都有自己的地址空间,遵循一次在一台机器上运行的单个程序的模型,就像计算早期所做的那样。在现代分时操作系统上,进程仍然看到世界,就好像它们正在使用专门为它们提供的 CPU 和内存运行一样。 (这有点简化,进程当然可以通过 IPC 机制了解其他进程。)

现在,让我们看看替代方案:由计算机上运行的所有进程共享的地址空间。由于程序启动时内存地址已被正在运行的进程使用,因此当程序加载到内存中时,必须重新定位内存段。程序的内存布局可能每次都不同,并且程序在启动之前必须“即时”重新链接。

共享内存空间可以通过将属于不同进程的页面分散在整个内存空间来实现。这需要在硬件中实现精心设计的保护方案,其中每个内存区域(页或段)将与有关哪个进程拥有该区域的信息相关联。该解决方案还有一个缺点,即内存会产生碎片,并可能导致程序无法加载,因为它可能需要具有连续内存地址的大区域,而足够大的区域可能不可用。

另一种方法是为每个进程保留连续的内存空间。这将使保护方案变得更简单(只有下限和上限),但会浪费地址空间,并且还会产生碎片。

与此有些相关的是共享库,其中包含许多不相关进程共享的代码和数据。共享库的页面最好应该不加修改地加载到内存中(即没有每个进程的绝对地址修补),否则物理内存帧不能在进程之间共享。另一方面,共享库通常必须加载到不同进程中的不同虚拟地址,否则它们会变得难以处理。现代共享库使用与位置无关的代码并通过间接访问数据,因此它们可以大部分不经修改地放置,并且仍然使用不同的虚拟地址运行。第一代Linux“a.out”共享库实际上更简单,并且加载到地址空间中的固定位置。这需要为每个已知共享库保留虚拟地址的中央注册表,并为未来的增长保留一些额外的空间。

相关内容