虚拟寻址与物理寻址
我不太明白“多个独立的虚拟地址,指向同一个物理地址”的好处,尽管我读了很多书籍和帖子,
例如,在类似的问题中 物理寻址和虚拟寻址概念的区别,
帖子声称程序不会崩溃彼此, 和
“一般来说,一个特定的物理页面仅映射到一个应用程序的 虚拟空间”
好吧,在 http://tldp.org/LDP/tlk/mm/ memory.html,在“共享虚拟内存”部分,它说
“例如系统中可能有多个进程正在运行 bash 命令外壳。与其拥有多份 bash 副本,不如拥有一份 每个进程的虚拟地址空间最好只有一个 复制到物理内存中并且所有运行 bash 的进程共享 它。”
一个物理地址(例如,shell程序)映射到两个独立的虚拟地址,这怎么可能不崩溃?这不是和使用物理寻址一样吗?
虚拟寻址提供了什么,这是不可能的或物理寻址方便吗?如果不存在虚拟内存,即两个直接指向相同的物理内存,我认为通过使用某种协调机制,它仍然可以工作。那么为什么还要麻烦“虚拟寻址,MMU,虚拟内存”这些东西呢? ?
I do not quite understand the benefit of "multiple independent virtual address, which point to the same physical address", even though I read many books and posts,
E.g.,in a similar question Difference between physical addressing and virtual addressing concept,
The post claims that program will not crash each other, and
"in general, a particular physical page only maps to one application's
virtual space"
Well, in http://tldp.org/LDP/tlk/mm/memory.html, in section "shared virtual memory", it says
"For example there could be several processes in the system running
the bash command shell. Rather than have several copies of bash, one
in each processes virtual address space, it is better to have only one
copy in physical memory and all of the processes running bash share
it."
If one physical address (e.g., shell program) mapped to two independent virtual addresses, how can this not crash? Wouldn't it be the same as using the physical addressing?
what does virtual addressing provide, which is not possible or convenient from physical addressing? If no virtual memory exists, i.e., two directly point to the same physical memory? i think, by using some coordinating mechanism, it can still work. So why bother "virtual addressing, MMU, virtual memory" these stuff?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
此功能有两个主要用途。
首先,您可以在进程之间共享内存,这些进程可以通过共享页面进行通信。事实上,共享内存是 IPC 最简单的形式之一。
但是共享只读页面也可以用来避免无用的重复:大多数时候,程序的代码在加载到内存中后不会改变,因此它的内存页面可以在运行该程序的所有进程之间共享。显然,只有代码是共享的,包含堆栈、堆以及程序的数据(或者,如果您愿意,状态)的内存页不共享。
这个技巧通过“写时复制”得到了改进。可执行文件的代码通常在运行时不会改变,但有些程序实际上是可以自我修改的(它们在过去很常见,当时大部分开发仍然是在汇编中完成的);为了支持这些东西,操作系统按照之前的说明进行只读共享,但是,如果它检测到共享页面之一上的写入,它会禁用该页面的共享,创建它的独立副本并让程序写入那里。
这个技巧在数据很可能不会改变但也有可能发生的情况下特别有用。
可以使用此技术的另一种情况是当进程分叉时:新进程与父进程共享,而不是复制每个内存页(如果子进程立即执行 exec 则完全无用)它的所有内存页面都处于写入时复制模式,允许快速创建进程,仍然“伪造”“经典”分叉行为。
There are two main uses of this feature.
First, you can share memory between processes, that can communicate via the shared pages. In facts, shared memory is one of the simplest forms of IPC.
But shared readonly pages can also be used to avoid useless duplication: most of times, the code of a program does not change after it has been loaded in memory, so its memory pages can be shared among all the processes that are running that program. Obviously only the code is shared, the memory pages containing the stack, the heap and in general the data (or, if you prefer, the state) of the program are not shared.
This trick is improved with "copy on write". The code of executables usually doesn't change when running, but there are programs that are actually self-modifying (they were quite common in the past, when most of the development was still done in assembly); to support this stuff, the operating system does read-only sharing as explained before, but, if it detects a write on one of the shared pages, it disables the sharing for such page, creating an independent copy of it and letting the program write there.
This trick is particularly useful in situations in which there's a good chance that the data won't change, but it may happen.
Another case in which this technique can be used is when a process forks: instead of copying every memory page (which is completely useless if the child process does immediately an
exec
) , the new process shares with the parent all its memory pages in copy on write mode, allowing quick process creation, still "faking" the "classic" fork behavior.就可以构建多个进程共享一块内存;例如,一个充当向内存写入的服务器,另一个充当从中读取的客户端,或者同时进行读取和写入。这是进行进程间通信 (IPC) 的一种非常快速的方法。 (其他解决方案,例如管道和套接字,需要将数据复制到内核,然后复制到共享内存跳过的其他进程。)但是,与任何 IPC 解决方案一样,程序必须协调它们的读取并通过某种消息传递协议写入共享内存区域。
此外,示例中的“系统中运行
bash
命令 shell 的多个进程”将共享其地址空间的只读部分,其中包括代码。它们可以同时执行相同的内存中代码,并且不会互相杀死,因为它们无法修改它。在报价中
“一般”部分实际上应该是“通常”:内存页面不共享,除非您将它们设置为共享,或者除非它们是只读的。
Multiple processes can be built to share a piece of memory; e.g. with one acting as a server that writes to the memory, the other as a client reading from it, or with both reading and writing. This is a very fast way of doing inter-process communication (IPC). (Other solutions, such as pipes and sockets, require copying data to the kernel and then to the other process, which shared memory skips.) But, as with any IPC solution, the programs must coordinate their reads and writes to the shared memory region by some messaging protocol.
Also, the "several processes in the system running the
bash
command shell" from the example will be sharing the read-only part of their address spaces, which includes the code. They can execute the same in-memory code concurrently, and won't kill each other since they can't modify it.In the quote
the "in general" part should really be "typically": memory pages are not shared unless you set them up to be, or unless they are read-only.