Memory management 虚拟寻址与物理寻址

Memory management 虚拟寻址与物理寻址,memory-management,operating-system,terminology,virtual-memory,virtual-address-space,Memory Management,Operating System,Terminology,Virtual Memory,Virtual Address Space,我不太明白多个独立虚拟地址的好处,它们指向同一个物理地址,尽管我读了很多书和帖子 例如,在一个类似的问题中 邮报声称程序不会互相崩溃,并且 通常,特定的物理页面只映射到一个应用程序的 虚拟空间 在共享虚拟内存部分,它说 例如,系统中可能有多个进程正在运行 bash命令shell。与其有几个bash副本,不如有一个 在每个进程的虚拟地址空间中,最好只有一个 在物理内存和运行bash共享的所有进程中复制 它 如果一个物理地址(例如外壳程序)映射到两个独立的虚拟地址,这怎么可能不会崩溃?这和使用物理寻

我不太明白多个独立虚拟地址的好处,它们指向同一个物理地址,尽管我读了很多书和帖子

例如,在一个类似的问题中

邮报声称程序不会互相崩溃,并且

通常,特定的物理页面只映射到一个应用程序的 虚拟空间

在共享虚拟内存部分,它说

例如,系统中可能有多个进程正在运行 bash命令shell。与其有几个bash副本,不如有一个 在每个进程的虚拟地址空间中,最好只有一个 在物理内存和运行bash共享的所有进程中复制 它

如果一个物理地址(例如外壳程序)映射到两个独立的虚拟地址,这怎么可能不会崩溃?这和使用物理寻址不一样吗

虚拟寻址提供了哪些物理寻址不可能或不方便的功能?如果不存在虚拟内存,即两个虚拟内存直接指向同一物理内存?我认为,通过使用一些协调机制,它仍然可以工作。那么为什么还要麻烦虚拟寻址、MMU、虚拟内存这些东西呢

如果一个物理地址(如外壳程序)映射到两个独立的虚拟地址

可以构建多个进程来共享一块内存;e、 g.其中一个充当向内存写入的服务器,另一个充当从内存读取的客户端,或者同时执行读写操作。这是一种非常快速的进程间通信方式。其他解决方案,如管道和套接字,需要将数据复制到内核,然后复制到另一个进程,共享内存会跳过该进程。但是,与任何IPC解决方案一样,程序必须通过某种消息传递协议协调对共享内存区域的读写

此外,系统中运行示例中bash命令shell的几个进程将共享其地址空间的只读部分,其中包括代码。它们可以并发执行相同的内存中代码,并且不会互相杀死,因为它们无法修改代码

在引用中

通常,特定的物理页面只映射到一个应用程序的虚拟空间

通常情况下,内存页应该是不共享的,除非您将它们设置为共享,或者它们是只读的

如果一个物理地址(如外壳程序)映射到两个独立的虚拟地址

可以构建多个进程来共享一块内存;e、 g.其中一个充当向内存写入的服务器,另一个充当从内存读取的客户端,或者同时执行读写操作。这是一种非常快速的进程间通信方式。其他解决方案,如管道和套接字,需要将数据复制到内核,然后复制到另一个进程,共享内存会跳过该进程。但是,与任何IPC解决方案一样,程序必须通过某种消息传递协议协调对共享内存区域的读写

此外,系统中运行示例中bash命令shell的几个进程将共享其地址空间的只读部分,其中包括代码。它们可以并发执行相同的内存中代码,并且不会互相杀死,因为它们无法修改代码

在引用中

通常,特定的物理页面只映射到一个应用程序的虚拟空间


通常情况下,内存页应该是不共享的,除非您将内存页设置为只读或只读。

此功能有两个主要用途

首先,您可以在进程之间共享内存,这些进程可以通过共享页面进行通信。事实上,共享内存是IPC最简单的形式之一

但共享只读页也可用于避免无用的重复:大多数情况下,程序的代码在加载到内存后不会更改,因此其内存页可以在运行该程序的所有进程之间共享。显然,只有代码是共享的,包含堆栈、堆和一般数据的内存页,或者,如果您愿意,程序的状态是不共享的

这一技巧通过写时复制得到了改进。可执行文件的代码在运行时通常不会更改,但有些程序实际上是自我修改的。在过去,当大多数开发仍然在汇编中完成时,它们非常常见;为了支持这种功能,操作系统会像前面解释的那样进行只读共享,但是,如果它检测到其中一个共享页面上有写操作,它会禁用该页面的共享,创建该页面的独立副本并让程序在其中写入

这种技巧在数据很有可能不会更改但可能会发生更改的情况下特别有用

另一种可以使用这种技术的情况是当一个进程分叉时
:如果子进程立即执行exec,则复制每个内存页是完全无用的,而不是复制每个内存页,新进程将以“写时复制”模式与父进程共享其所有内存页,从而允许快速创建进程,同时仍假装经典的fork行为

此功能有两个主要用途

首先,您可以在进程之间共享内存,这些进程可以通过共享页面进行通信。事实上,共享内存是IPC最简单的形式之一

但共享只读页也可用于避免无用的重复:大多数情况下,程序的代码在加载到内存后不会更改,因此其内存页可以在运行该程序的所有进程之间共享。显然,只有代码是共享的,包含堆栈、堆和一般数据的内存页,或者,如果您愿意,程序的状态是不共享的

这一技巧通过写时复制得到了改进。可执行文件的代码在运行时通常不会更改,但有些程序实际上是自我修改的。在过去,当大多数开发仍然在汇编中完成时,它们非常常见;为了支持这种功能,操作系统会像前面解释的那样进行只读共享,但是,如果它检测到其中一个共享页面上有写操作,它会禁用该页面的共享,创建该页面的独立副本并让程序在其中写入

这种技巧在数据很有可能不会更改但可能会发生更改的情况下特别有用


另一种可以使用这种技术的情况是当一个进程分叉时:如果子进程立即执行exec,那么复制每个内存页是完全无用的,而新进程不是复制每个内存页,而是以写时复制模式与父进程共享其所有内存页,允许快速创建进程,仍然假装经典的分叉行为

嗨,拉斯曼,非常感谢你的评论。但是,虚拟寻址提供了什么,而物理寻址既不可能也不方便?如果不存在虚拟内存,即两个虚拟内存直接指向同一物理内存,那么具体成本是多少?我认为,通过使用一些协调机制,它仍然可以工作。那么,为什么还要麻烦虚拟寻址、MMU、虚拟内存这些东西呢?@pepero:虚拟内存是对物理内存的一种抽象,它使每个进程都不被其他进程所注意,从而保护其地址空间免受您担心的溢出。此外,在没有虚拟寻址的情况下,每个进程必须在启动时确定其代码和数据所在的位置,并相应地设置其指针。如果它出错,它可能会损坏自己的内存或其他进程的内存。嗨,larsmans,非常感谢您的评论。但是,虚拟寻址提供了什么,而物理寻址既不可能也不方便?如果不存在虚拟内存,即两个虚拟内存直接指向同一物理内存,那么具体成本是多少?我认为,通过使用一些协调机制,它仍然可以工作。那么,为什么还要麻烦虚拟寻址、MMU、虚拟内存这些东西呢?@pepero:虚拟内存是对物理内存的一种抽象,它使每个进程都不被其他进程所注意,从而保护其地址空间免受您担心的溢出。此外,在没有虚拟寻址的情况下,每个进程必须在启动时确定其代码和数据所在的位置,并相应地设置其指针。如果它出错,它可能会损坏自己的内存或其他进程的内存。