Tar*_*rik 36 paging virtual-memory virtual-address-space
我一直在学习这些主题并阅读了许多文章和书籍,但他们都缺乏一些补充信息,让我更加困惑.所以在这里,我想在我提出问题时解释我所知道的.希望这个主题对我这样的人有用.如果有必要,我还想学习我的知识和更正的有效性.
虚拟内存
有些文章说"虚拟内存是硬盘的一些空间,模拟物理内存,这样我们就可以拥有比实际更多的内存." 其他一些文章说"虚拟内存是物理内存(RAM)的组合,硬盘的一部分就像物理内存和页面表."然而它们是不同的东西,我不明白为什么有这样的不同解释.
让我们来看第二个解释,因为维基百科也是如何描述虚拟内存的.此时虚拟地址是有意义的,因为我们直接使用虚拟内存中的地址而不是物理内存.
顺便说一句,我的Mac说我有8GB的物理内存和8GB的虚拟内存.在这种情况下,VM是否包含物理内存,还是HD用作内存的空间量?我的程序有16GB内存吗?
问题1:
Intel i5具有36位地址总线,这意味着您可以寻址64GB内存.假设我在我的电脑上安装了4GB RAM.但是,我的程序可能不知道所安装内存的大小,因为它将在具有不同内存大小的许多不同系统上使用.这就是虚拟内存变得方便的地方.它抽象出安装的内存的实际大小.
但是,当我的程序想要访问内存地址0xFFFFFFFFF时会发生什么?我只安装了4GB,也许还有一些高清内存空间.
我对这个问题有两个理论:
1.由于页面表由操作系统维护,操作系统对该地址进行解码,找出哪个页面并检查页面表中的页面,看看它们是否有与之关联的物理地址(有效和无效标志),如果是然后转到虚拟地址中定义的物理内存+偏移量中的页面入口点的物理地址并带来该值.否则会发生页面错误,操作系统在辅助存储中查找该页面,获取它并将其放入内存并更新页面表.
2.它抛出OutOfMemory类型的异常,表示我没有任何给定地址可以解决的内存.
第一个理论的缺点是当程序想要使用64GB内存时会发生什么?然后我们需要有60GB的高清内存空间,因为我们只有4GB.但是,在屏幕截图下面MAC告诉我,只有8GB的虚拟内存.
问题2:
进程如何放入虚拟内存?我的意思是每个进程都有可用的0x0 - 0xFFFFFFFFF虚拟内存空间,或者只有一个虚拟内存地址空间可以放置所有进程吗?
如果每个进程都假定它们具有可用的所有内存,则内存如下所示:
如果只有一个虚拟内存概念,那么它将如下所示:
页表
因此,页表是位于物理地址和虚拟地址之间的数据结构.它是一个关联数组(或类似字典),对于每个页面(键),都有一个物理地址关联(值).
OS使用MMU(内存管理单元)执行从虚拟地址到物理地址的转换.
问题3:
是否有一个巨大的巨型页面表,其中包含每个进程的所有页面,或者每个进程都有自己的页面表?
分页
分页是一种内存管理方法.虚拟内存和物理内存由内存管理单元分为页面(固定和相同大小的块).当您在内存和辅助存储之间交换页面时,此技术非常有用,以便您可以在它们之间交换页面.例如,您的程序请求位于地址中的数据.但是,程序使用的地址是虚拟地址,MMU使用页表对其进行转换.在此期间,MMU检查页表是否在页表中存在所请求的内容,如果不是,则OS从辅助存储器获取它并更新页表.
问题4:
假设一个进程从一个地址请求数据,该地址被转换为已经有一些数据的物理地址.如何知道数据不属于请求者进程,应该替换为辅助存储中的数据?
例如,有脏位用于是否将该页面写回硬盘,但我不认为这是决定所有者进程的原因.
Emm*_*met 17
在我回答你的问题之前(我希望我这样做),这里有一些介绍性的评论:
这里的问题是"虚拟内存"有两种感觉.作为低级程序员使用的技术术语,"虚拟内存"(几乎)与消费者所解释的"虚拟内存"无关.
在技术意义上,"虚拟内存"是一种内存管理系统,每个进程都有自己的虚拟地址空间,并且该内核空间中的内存地址由OS内核映射到物理内存地址并提供硬件支持(使用TLB之类的术语,多级页表,页面错误和散步等).这是您感兴趣的VM感(如下所述).
在非技术意义上,"虚拟内存"是代替RAM使用的磁盘空间(使用交换,后备存储等术语).这是你对VM并不特别感兴趣的虚拟感,但似乎你已经看到了一些主要涉及这个术语或者混淆两者的材料.
当我的程序想要访问内存地址0xFFFFFFFFF时会发生什么?我只有4GB
在这种情况下,你的"理论1"更接近.
VM从物理地址中解耦程序"看到"并使用的地址 - 虚拟地址.您的4GiB内存可能位于从0x0到0xFFFFFFFF(8 F)的物理地址,但地址0xFFFFFFFFF(9 F)位于虚拟地址的用户空间(在规范布局中).如果0xFFFFFFFFF位于分配给进程的块中,则CPU和内核(一致)将页面地址0xFFFFFF000(假设4k页面,我们只是将低12位破解)转换为真实的物理页面,这可能具有(几乎)任何物理基地址.假设该页面的物理地址是0xeac000(当内核为您提供虚拟页面0xFFFFFF000时建立的关系),则虚拟地址0xFFFFFFFFF处的字节位于物理地址0x00eacfff.
当您取消引用0xFFFFFFFFF(假设4k页)时,内核"请求"CPU访问该虚拟地址,并且CPU切断低12位,并在dTLB中查找页面(转换后备缓冲区是虚拟到 - 物理页面映射缓存;至少有一个用于数据,一个用于指令).如果有命中,CPU会构造真实的物理地址并获取值.如果存在TLB未命中,则CPU引发页面错误,这会导致内核查询(或"遍历")页表以确定正确的物理页面,并将该值"返回"到CPU,该CPU将其缓存在dTLB(很可能几乎立即重用).内核然后要求该地址的CPU 再次,这一次,它会不会触发散步成功.
我承认这个描述非常糟糕(反映了我自己的知识水平).特别是,在TLB中识别特定过程的确切方式对我来说并不是100%清楚,至少在某种程度上是硬件特定的.过去,每个上下文切换都需要一个完整的TLB刷新,但是更新的Intel CPU有一个6位"PID"字段,这意味着在上下文切换时并不总是需要刷新,有时仍需要刷新.由于我未能描述多级TLB,PTE(页表条目)并在数据和指令缓存中解决这一问题的重要性(尽管我知道现代硬件可以看到地址是否完全可能),因此产生了进一步的崩溃.在一些缓存级别与TLB查找同时).
进程如何放入虚拟内存?我的意思是每个进程都有可用的0x0 - 0xFFFFFFFFF虚拟内存空间,或者只有一个虚拟内存地址空间可以放置所有进程吗?
每个进程都有自己完全不同的虚拟内存空间.这(几乎)是VM的整个要点.
在过去,TLB在任何意义上都不是"过程意识".每个上下文切换意味着必须完全刷新TLB.如今,TLB条目有一个简短的"进程上下文"(PCID?)字段并支持选择性刷新,因此您可以将其视为PID(或者更确切地说,PCID:PID的某种散列)预先附加到虚拟页面地址,因此TLB更能识别进程,并且当与另一个进程发生PCID冲突时,只需要刷新那些条目(两个进程映射到同一个PCID).
是否有一个巨大的巨型页面表,其中包含每个进程的所有页面,或者每个进程都有自己的页面表?
当然,这是特定于操作系统的,但我的理解是Linux有一组多级页表,其中条目(PTE)用PID标记,而不是单独的每进程页表.我认为这个的基本原因是许多虚拟到物理映射是n:1而不是1:1,因为它们都是1:1会在很大程度上打败VM的主要目的:想想包含共享的只读页面库之类的指令libc
,或者在fork之后在父级和子级之间共享的写时复制数据页.在创建/退出进程时,为每个进程页表中的每个进程复制这些条目的效率低于向/从一组公共页表添加/删除进程特定条目的效率.
一旦拥有了VM系统,在发生页面错误时添加从磁盘检索页面的功能变得非常简单,并为PTE实现"老化",以便将最近最少使用的页面放在磁盘上.虽然这是内存受限系统的一个重要特性,但与理解VM系统的实际工作方式几乎完全无关.
Str*_*ior 13
有些人使用术语"虚拟内存"就好像它是页面文件的同义词一样,因为页面文件代表分配的内存中不是"真实"内存(即RAM)的部分.但大多数人认为"虚拟内存"是操作系统为程序提供的整个抽象层,它将RAM和页面文件结合在一起.
我不确定Mac OS会支持哪些这些定义,尽管您的计算机似乎不会分配任何分页内存,所以我猜它可能会为您的8GB实际RAM增加8GB的分页内存,总共16GB的可用(虚拟)内存.
请记住,因为操作系统管理内存分配和释放请求,所以可以随心所欲地执行任何操作.我的理解是,大多数操作系统为每个进程都有不同的内存分配表,因此它们可以为多个程序提供相同的虚拟内存地址,但这些内存地址将映射到内存中的不同实际块.因此,64位操作系统可以将最大数量的32位地址分配给多个32位程序 - 它们并不仅限于相同的32位内存地址.
但是,存在限制:操作系统可以将限制设置为允许页面文件增长到的大小.因此,除非您故意告诉操作系统这样做,否则它可能不会有64 GB的总虚拟内存.即使它确实如此,它也无法为每个程序分配所有64 GB,因此OutOfMemory
在操作系统0xFFFFFFFFF
为您的程序分配虚拟地址之前,您很可能会遇到错误.(事实上,我不会惊讶地发现它0xFFFFFFFFF
实际上是一个保留的错误代码位置,类似于0x0
.)但是由于你的程序知道的地址与真实的内存地址无关,所以你可能会最终被分配一个程序认为的内存地址0xFFFFFFFFF
,即使操作系统没有在那么多内存附近使用.
是否有一个巨大的巨型页面表,其中包含每个进程的所有页面,或者每个进程都有自己的页面表?
可能两者......然后是一些.
因此,假设一个进程已经在地址中分配了内存0x00000002
,当它从该内存地址加载该值时,操作系统可能会认识到这实际上映射到了实际的内存地址0x00000F23
,而这个内存地址的值实际上是被提取到CPU寄存器.或者,它可以意识到它已经将包含该地址的页面移动到某个地方的磁盘上,在这种情况下,操作系统将找到一个空的内存部分,并首先将页面的数据从磁盘加载到该内存中.(同样,此内存地址与程序请求的原始内存地址没有任何关联.)
如果没有任何空的内存来拉取页面,操作系统将首先将一些数据从内存中移出并进入页面文件.它试图智能地确定哪个内存在不久的将来最不可能使用.但有时候你最终会在内存被交换到磁盘后不断被请求,只能替换程序要求的下一块内存.这种"颠簸"导致计算机内存不足的情况变得非常非常慢,因为磁盘访问比内存访问慢几个数量级.
归档时间: |
|
查看次数: |
13361 次 |
最近记录: |