Operating system 在虚拟内存中,两个不同的进程可以有相同的地址吗?

Operating system 在虚拟内存中,两个不同的进程可以有相同的地址吗?,operating-system,Operating System,这是我在一个网站上找到的一个访谈问题,问题是:“在虚拟内存中,两个不同的进程是否可以有相同的地址?如果回答“否”,这是正确的,那么一个进程如何访问另一个进程的内存,例如,调试器可以访问变量并在调试时更改它们?” 我的理解是: 2差异进程可以具有相同的虚拟内存地址。这是因为每个进程都有自己的页表。每个进程都将其视为32位机器上的4Gb内存。因此P1和P2都可以访问地址0xabcdef,但物理内存位置可能不同。对不对 调试器的工作原理相同-2个进程可以访问相同的地址。因此,它可以动态修改变量等 是的

这是我在一个网站上找到的一个访谈问题,问题是:“在虚拟内存中,两个不同的进程是否可以有相同的地址?如果回答“否”,这是正确的,那么一个进程如何访问另一个进程的内存,例如,调试器可以访问变量并在调试时更改它们?”

我的理解是:

  • 2差异进程可以具有相同的虚拟内存地址。这是因为每个进程都有自己的页表。每个进程都将其视为32位机器上的4Gb内存。因此P1和P2都可以访问地址0xabcdef,但物理内存位置可能不同。对不对

  • 调试器的工作原理相同-2个进程可以访问相同的地址。因此,它可以动态修改变量等


  • 是的,根据引用同一地址的进程,同一地址完全有可能映射到不同的物理内存。事实上,在Windows下就是这样。

    有时我觉得自己像美能达广告中的“长者”。。。20世纪60年代,Multics是使用虚拟内存创建的。最后一个Multics系统于2000年10月30日17时08分关闭

    在Multics中,无论有多少用户在运行程序,内存中只存在程序的一个副本。这意味着每个用户进程都有相同的程序物理地址和虚拟地址

    当我查看Windows任务管理器并看到一个程序的多个副本(例如svchost.exe)时,我想知道为什么/如何丢失Multics中的革命性概念。

    1)

    • 同一时间相同的物理内存地址:否
    • 同时使用相同的虚拟内存地址:是(每个虚拟内存地址映射到不同的网络物理地址或交换空间)
    2) 我认为调试器不会直接访问被调试的另一个进程,而是与被调试进程中的运行时通信以进行更改


    也就是说,如果您有权,操作系统或处理器指令可能会提供对他人内存访问的访问/修改。这并不意味着它有相同的地址,它只是说进程1可以说“在进程2中访问内存@address1”。有人(处理器/操作系统/运行时)将为进程1执行此操作。

    在32位系统中,每个进程都有4GB的地址空间。真正的4GB是由操作系统管理的。因此,原则上2个不同的进程可以具有相同的本地地址

    现在,当一个进程必须读取另一个进程的内存时,它必须与另一个进程通信(内存映射文件等),或者使用调试API,如OpenProcess/ReadProcessMemory


    我确信的是,至少在Win32中,如果没有操作系统的帮助,一个进程不能直接读取另一个进程的虚拟内存。

    理论上,任何当前流行的操作系统(Win、linux、unix、Sol等)中用户执行的每个进程最初都允许使用4gig的地址范围(32位平台上的0x00000000 t0 0xffffffff),无论是一个简单的hello world程序还是它复杂的web容器托管stackoverflow站点。这意味着每个进程都有其范围,从相同的起始地址开始,实际上以相同的地址空间结束。显然,每个进程在各自的虚拟地址空间范围内都有相同的虚拟地址。所以第一个问题的答案是肯定的

    不同之处在于,当操作系统执行任何进程时,现代操作系统都是多任务操作系统,并且在任何时间点运行多个进程。因此,在主内存中容纳每个进程的4gig根本不可行。因此,操作系统使用分页系统,将虚拟地址范围(0x00000000到0xFFFFFF)划分为4k大小的页面(并非总是如此)。因此,在启动进程之前,它实际上会将初始时所需的页面加载到主内存中,然后根据需要加载另一个虚拟页面范围。因此,将虚拟内存加载到物理内存(主内存)被称为内存映射。在此过程中,您将根据主内存中的可用插槽将页面的虚拟地址范围映射到物理地址范围(如ox00000000到ox00001000虚拟地址范围到0x00300000到0x00301000物理地址范围)。因此,在任何时间点,只有一个虚拟地址范围将映射到该特定的物理地址范围,所以第二个问题的答案是否定的

    但是

    共享内存概念是一个例外,所有进程都可以彼此共享它们的一些虚拟地址范围,这些虚拟地址范围将映射到一个公共物理地址空间。因此,在这种情况下,答案可以是肯定的

    例如,在Linux上,每个可执行文件都需要libc.so库来执行程序可执行文件。每个进程加载它们所需的库,并在它们的地址空间中为它们分配一些虚拟地址页范围。现在考虑一个场景,其中执行100个进程,每个进程需要这个库LICBC。因此,如果操作系统在每个进程中为这个库libc.So分配虚拟地址空间,然后您可以想象libc.so库的复制级别&很有可能在任何时候,主内存中都会有多个libc.so地址范围页实例。因此,要使其成为冗余操作系统,将libc.so加载到每个进程的特定虚拟地址空间范围,该范围映射到内存中的固定物理地址范围所以每个进程都会引用固定的物理地址范围来执行libc.So中的任何代码。因此,在这种情况下,每个进程也共享一些物理地址范围

    但在用户malloced虚拟地址范围映射中,两个进程不可能同时具有相同的物理地址


    希望有帮助。

    @dbasnett:这是一个术语问题,不是吗?每个用户都需要自己的堆栈、指令指针和堆,即使“只有一个程序”在运行,不是吗?这些都封装在一个进程i中