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

时间:2010-08-24 00:08:51

标签: operating-system

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

我的理解是:

  1. 2 diff进程可以具有相同的虚拟内存地址。这是因为每个进程都有自己的页表。每个进程都认为它是32位机器上的4Gb内存。因此P1和P2都可以访问地址0xabcdef - 但物理内存位置可能不同。这不对吗?

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

5 个答案:

答案 0 :(得分:22)

理论上,用户在任何当前流行的操作系统(Win,linux,unix,Sol等)中执行的每个进程最初都允许使用4gig的地址范围(在32位平台上为0x00000000 t0 0xffffffff),无论它是一个简单的hello世界程序或其复杂的Web容器托管stackoverflow site.It意味着每个进程的范围从相同的起始地址开始,并以相同的地址空间结束,并且以VIRTUALLY结尾。因此,显然每个进程在其各自的虚拟地址空间范围内具有相同的虚拟地址。所以你的第一个问题的答案是肯定的。

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

BUT

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

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

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

希望它有所帮助。

答案 1 :(得分:8)

1)

  • 同时使用相同的物理内存地址:否
  • 同时使用相同的虚拟内存地址:YES(每个地址映射到不同的物理地址或交换空间)

2)我认为调试器不会直接访问已调试的其他进程,而是在调试过程中与运行时进行通信以进行更改。

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

答案 2 :(得分:3)

是的,根据引用它的过程,同一地址绝对可以映射到不同的物理内存。事实上这就是Windows下的情况。

答案 3 :(得分:1)

有时我觉得美能达商业中的“老人”......在1960年代,Multics是使用虚拟内存创建的。最后一个Multics系统于2000年10月30日17:08Z关闭。

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

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

答案 4 :(得分:1)

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

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

我确信在没有操作系统帮助的情况下,一个进程无法直接在Win32中直接读取其他进程的虚拟内存。