我正在阅读虚拟内存,据我所知,每个进程都有自己的VM表,可以将VM地址映射到实际内存中的物理地址。因此,如果进程持续分配对象,则它们可能存储在物理内存中完全不同的位置。我的问题是,如果我分配和应该存储在连续的内存块中的数组,并且如果数组的大小需要比一个页面可以提供的空间更多的空间,据我所知,该数组将连续存储在VM中但可能在PM完全不同的位置。它是否正确?如果我误解了VM是如何工作的,请纠正我。如果它是正确的,这是否意味着我们只关心VM中的分配是否连续?
答案 0 :(得分:2)
没错。数组必须只对您的应用程序看起来是连续的,但可能在物理上分散在内存中。
答案 1 :(得分:2)
现在的内存处理程序是否真的不知道物理内存中是否与页面边界重叠的内容实际上是连续的。内存粘合逻辑基本上将所有可寻址内存页面视为无序集合,并且排序基本上与进程相关联;不能保证对于不同的进程最终被分配相同的两个物理内存页面(在不同的时间点),这些物理页面之间的表达关系将是相同的。实际上,CPU和处理这些东西的内存之间有一个转换层。
答案 2 :(得分:1)
我只想添加/清楚地表明,从用户空间程序的角度来看,一块分配的内存始终显示为连续。操作系统与CPU的内存管理单元(MMU)一起处理所有虚拟到物理内存映射,程序员从不需要担心如何处理这种映射(当然,除非程序员是编写操作系统)。
编译器(或在汇编中编写代码的编译器)可以将程序的地址视为从0开始,直到该特定程序所需的最大地址为止。然后,操作系统为每个进程创建一个页表,并使用该表对每个虚拟内存位置的物理地址进行部分解码。操作系统将程序中的地址视为两个独立的部分,页面地址和该页面的偏移量。然后,MMU将页面地址转换为物理帧地址。注意,从OS的角度来看,物理存储器“帧”类似于概念“页面”;这两个具有相同的大小(例如4096字节)。
由于物理内存被划分为相同大小的帧,并且页面大小与帧大小相同,因此您可以知道您的虚拟地址有多少用作页面位置以及该页面的偏移量。例如,如果您的操作系统为每个进程“分配”4千兆字节(如Linux中的情况),并且您的页面/帧大小为4096字节,则可以知道20位(4,294,967,296字节/ 4096字节= 2 ^ 20 =将32位地址的1,048,576页/页地址用作页面地址,然后由MMU将其转换为物理帧地址,其余12位用作偏移量以确定地址起始位置从页面/框架的开头。
VM(用户速度)地址 - >页面+偏移(OS) - >帧+偏移量(MMU)=物理地址