当虚拟地址空间大于物理内存时,OS可以使用交换来逐出页面帧(例如,将LRU逐出)。 CPU生成页面错误,然后将磁盘中的页面交换到主内存中。当虚拟地址足够大而主内存或磁盘都没有足够的存储空间来保存该地址时,会发生什么?当页面框架也不在磁盘中时会发生什么?是另一个页面错误吗?
答案 0 :(得分:0)
当虚拟地址足够大而主内存或磁盘都没有足够的存储空间来保存它时,会发生什么?
虚拟内存系统在辅助存储中维护逻辑地址空间的映像。一个设计良好的操作系统将不允许进程映射一个逻辑地址,该逻辑地址在辅助存储中尚无备份。当您的应用程序调用系统服务以将页面映射到逻辑地址空间时,如果页面没有辅助存储,则调用将失败。
当页面框架也不在磁盘中时会发生什么?
有些设计不佳的操作系统会映射页面,而没有后面的二级存储。您调用系统服务来映射页面,即使无法将页面备份到辅助存储中,该服务也会成功。 在那种情况下,您在访问时会遇到内存异常(并且在您的应用程序中没有任何提示,即真正的问题是内存分配失败)。
是否还有另一个页面错误?
否。
在逻辑内存系统(大多数处理器支持)中,页面具有两种状态:
1. Mapped
2. Unmapped
在虚拟内存系统中,存在三种状态:
1. Mapped
2. Unmapped and valid
3. Unmapped and invalid
发生页面错误时,处理器仅知道该页面未映射到内存。然后,操作系统必须确定该页面是否位于某个地方的辅助存储中。如果不是,则该操作使进程看到异常。如果是这样,则操作系统将加载并映射页面,然后让该过程以愉快的方式继续进行。
答案 1 :(得分:0)
当虚拟地址空间大于物理内存时,操作系统可以使用交换来逐出页面帧(例如,将LRU逐出)
让我们假设一个虚拟地址是48位(因此一个虚拟地址空间的大小是256 TiB),并且您正在运行123个进程,其中每个进程都有自己的虚拟地址空间。这总共增加了31488 TiB的虚拟地址空间。 注意:对于运行现代操作系统(Windows,Linux等)的现代80x86 PC,这是“非常正常”。
在这31488 TiB中:
几乎所有内容都将不被使用并标记为“不存在”。如果软件尝试访问它,则会出现页面错误,页面错误处理程序会意识到这是一个错误,并且您最终可能会遇到SIGSEGV
(或“死亡蓝屏”或...)。因为不被使用,所以操作系统不需要任何RAM或磁盘空间。
其中一些将相同的东西一次加载到RAM,然后映射到许多虚拟地址空间。这对于内核本身和共享库/ DLL是非常普遍的。它还包括以下情况:相同的RAM用于虚拟文件系统缓存和内存映射文件,或者同一RAM作为“共享内存”映射到2个或更多进程,或者同一RAM被映射到2个或更多进程。虚拟地址空间为“写入时复制”(例如,在fork()
之后)。
一些将“在写入时分配”-字面相同的页面充满了零,它们映射到许多虚拟地址空间中的许多虚拟地址,如果您对其进行写入,则会得到页面错误,并且页面错误处理程序将对其进行分配您尝试写入的页面的RAM的新页面。这样,操作系统就可以假装在不使用任何RAM或任何磁盘空间的情况下分配了大量的虚拟空间并将其填充为零(直到实际对其进行了修改)。
某些将是(修改过的)特定过程唯一的数据。
最终结果是,总虚拟空间的31488 TiB可能只需要几GiB的RAM(并且可能根本不会使用交换空间)。
过量提交
操作系统做了很多技巧来假装实际上没有分配的内存。这会导致出现最坏情况的可能性,在这种情况下,实际上需要分配OS假装的所有内存。有两种方法可以解决此问题:
a)如果您无法解决最坏的情况,请拒绝让进程分配更多空间(例如,当进程尝试分配超出操作系统可以提供的容量时,返回“内存不足”错误)。这很糟糕,因为最坏的情况极不可能发生,并且您最终会无缘无故地出现软件故障(当实际上有足够的内存来满足当前需求时会出现“内存不足”)。
b)允许进程分配更多(在合理的范围内),即使您无法解决最坏的情况。在大多数情况下,这种方法都能正常工作,但是如果最坏的情况确实发生了,则必须中断某些操作(例如,操作系统终止进程以释放一些RAM)。
最好的选择(我认为)是第一个选择(不允许过量使用),但是要有大量的交换空间。实质上;这就像“允许过量使用RAM,但不允许过量使用交换空间+ RAM”;在必须开始告诉进程“没有更多的内存”之前,操作系统可能运行缓慢(由于过度使用交换空间)的位置;并且在大多数情况下,所有内容都将存储在RAM中(理想情况下,交换空间仅用于覆盖不太可能的最坏情况)。