虚拟内存管理器(VMM)性能概述

虚拟地址空间划分成段。每段的大小是 256 MB,它是虚拟内存地址空间中一个邻接的部分,数据对象可映射到该空间。
进程对数据的寻址能力按段(或对象)的级别进行管理,所以段既可以在进程间共享,也可以进行专门维护。例如,进程可共享代码段但拥有独立和专用的数据段。

实际内存管理
虚拟内存段划分成固定大小的单元叫做页。缺省页面大小是 4096 字节。某些系统也支持大页面,通常只能通过系统调用 shmat 访问。段中的每页在需要之前可位于实际内存(RAM)中,或存储在磁盘上。同样,实际内存也可以划分成 4096 字节的页面帧。VMM 的角色是管理分配实际内存页面帧并且解析程序对虚拟内存页面的引用,这些页面当前不在实际内存中或还不存在(例如,当进程第一次引用其数据段的某一页时)。
因为在任何给定时刻使用的虚拟内存数量可能比实际内存大,所以 VMM 必须将余量存储在磁盘上。从性能的观点来看,VMM 有两个稍微对立的目标:
·最小化使用虚拟内存的总处理器时间和磁盘带宽代价 
·最小化缺页故障的响应时间代价
在跟踪这些目标时,VMM 维护一个页面帧的空闲列表,它可用于补偿缺页故障。VMM 使用了一个页面替换算法来确定当前处于内存中的哪些虚拟内存页要将它们的页面帧重新指定到空闲列表中。页面替换算法使用了几个机制:
·虚拟内存段分成持久段或工作段。 
·虚拟内存段分成包含计算内存或文件内存。 
·跟踪在访问时引起缺页故障的虚拟内存页。 
·缺页故障分成新页故障或重新调页故障。 
·在每个虚拟内存段中维护一个重新调页故障率的统计信息。 
·用户可调阈值影响页面替换算法的结果。

以下各节较详细地描述了空闲列表和页面替换机制。
空闲列表
VMM 维护一个空闲页面帧的逻辑列表,它用于解决缺页故障。在绝大多数环境中,VMM 偶尔必须通过重新指定由运行进程占有的一些页面帧来添加到空闲列表中。需要重新指定页面帧的虚拟内存页由 VMM 的页面替换算法进行选择。VMM 阈值决定了重新指定的帧的数量。
持久段与工作段对比
持久段的页面在磁盘上的存储位置是永久性的。包含数据或可执行程序的文件映射到持久段中。因为持久段的每一页都有永久的磁盘存储位置,所以当页面被更改且不能再留在实际内存中时,VMM 将该页写回到那个位置。当页面被选择放置到空闲列表中时,如果它没有更改过则不需要 I/O 操作。如果后来再次引用到该页,那么就从它的永久磁盘存储位置读入一个新副本。
工作段是暂时的,它们仅在由进程使用时才存在,且没有永久的磁盘存储位置。进程堆栈和数据区域映射到工作段,这一点和内核文本段、内核扩展文本段、共享库文本段和数据段相同。当工作段的页面不能保存在实际内存中时,它们也必须占有磁盘存储位置。磁盘调页空间就是用于这个目的。
下列插图显示某些类型的段和它们的页面在磁盘上的位置之间的关系。它还显示了页面在实际内存中时实际(专有)的位置。
图形 持久和工作存储段. 该插图显示某些类型的段和它们的页面在磁盘上的位置之间的关系。它还显示了页面在实际内存中时实际(专有)的位置。工作段是暂时的,这意味着它们仅在由进程使用时才存在并且没有永久的磁盘存储位置。进程堆栈和数据区域映射到工作段,这一点和内核文本段、内核扩展文本段、共享库文本段和数据段相同。当工作段的页面不能保存在实际内存中时,它们也必须占有磁盘存储位置。磁盘调页空间就是用于这个目的。

持久段类型可进一步划分。客户段用于映射远程文件(例如,正通过 NFS 访问的文件),包括远程可执行程序。客户段的页面通过网络保存和恢复到它们的永久文件位置,而不是在本地磁盘调页空间。日志和延迟段是必须自动更新的持久段。如果选择从实际内存中除去(调出页)的页面来自于某个日志段或延迟段,那么必须将它写到磁盘调页空间中,除非它处于一种允许它提交(写到它的永久文件位置)的状态。
计算内存对比文件内存
计算内存也称为计算页面,它由属于工作存储器段或程序文本(可执行文件)段中的页面组成。
文件内存(或文件页面)由其余页面组成。这些通常是来自持久存储器中永久数据文件的页面。
页面替换
当空闲列表中可用的实际内存帧数量减少时就会调用一个页面替换器(stealer)。页面替换器在整个页面帧表(PFT)中移动,寻找可替换(steal)的页面。
PFT 中包含一些标志用来表示哪些页已经被引用,哪些页已经被修改。如果页面替换器遇到一个已经引用的页,它不会替换这个页而是为该页重新设置引用标志。在下一次钟针(页面替换器)经过该页且引用位仍未启用时,它便被替换。初次通过时未被引用的页面会立即得到替换。
修改标志表示该页进入内存后上面的数据已经改变。当页面要被替换时,如果设置了修改标志,那么在替换该页之前进行页面调出调用。属于工作段的页面写入调页空间;而持久段中的页面写到磁盘上。
图形 页面替换示例. 此插图从三个表中摘选而成。第一个表是具有四列的页面帧表,它包含实际地址、段类型、引用标志和修改标志。第二个表叫做空闲列表,它包含所有空闲页的地址。最后一个表代表除去所有空闲地址后最终得到的页面帧表。

除了页面替换以外,算法还可通过使用一个包含最近缺页故障标识的历史缓冲区来跟踪新页故障(第一次引用)和重新调页故障(引用已经调出的页)。然后它可以尽量平衡文件(持久数据)页面的调出和计算(工作存储器或程序文本)页面的调出。
当进程退出时,它的工作存储器立刻释放并且它的关联内存帧也放回到空闲列表中。然而由该进程打开的任何文件可保留在内存中。
如果线程在单处理器上运行,那么页面替换可直接在线程作用域中进行。在多处理器系统中,页面替换通过内核进程 lrud 进行,在达到阈值 minfree 时,该进程被分派到 CPU 中。从 AIX 4.3.3 开始,内核进程 lrud 是多线程的,每个存储池中一个线程。根据 CPU 数量和 RAM 大小将实际内存划分成平均大小的存储池。系统中存储池的数量可通过运行命令 vmtune -A 来确定。
在 AIX 4.3.3 和后续版本中,使用命令 vmtune -m <number of memory pools> 更改存储池数量,这将在系统引导时进行配置。数值 minfree 和 maxfree 在命令 vmtune 的输出中,它们是每个存储池的 minfree 和 maxfree 的总和。
重新调页
缺页故障要么是新页故障要么是重新调页故障。如果没有最近引用页面的记录的话,会出现一个新页故障。而出现重新调页故障是指一个知道其最近已经引用的页再次被引用,但由于该页在上次访问后已经被替换(可能写到磁盘上)而在内存中找不到它。
理想的页面替换策略通过总是替换那些不会再次引用的页面帧而完全减少重新调页故障(假设有足够的实际内存)。因而重新调页故障数是页面替换算法有效性的一个相反评测标准,算法将频繁被重用的页面保存在内存中,从而降低了总体 I/O 需求并潜在地改善了系统性能。
为了分清一个缺页故障是新页故障还是重新调页故障,VMM 维护一个重新调页历史记录缓冲区,它包含 N 个最近缺页故障的页面标识,其中 N 是内存可保留的帧数。例如,512 MB 内存需要一个 128 KB 的重新调页历史记录缓冲区。在页面调进时,如果它的标识可在重新调页历史记录缓冲区中找到,则将它计为一个重新调页。VMM 还可以分别评估计算内存重新调页率和文件内存重新调页率,只需为每种类型的内存维护重新调页故障计数即可。每次页面替换算法运行时都将重新调页率乘以 0.9,这样可比历史重新调页活动更有力地反映最近的重新调页活动。
VMM 阈值
几个数字阈值定义了 VMM 的目标。当超出这些阈值中的一个时,VMM 会采取适当的操作将内存状态恢复到限定范围内。本节讨论的阈值可由系统管理员用命令 vmtune 进行更改。
空闲列表中页面帧的数量受下列参数控制:
minfree 
空闲列表中可接受的实际内存页面帧的最小数量。当空闲列表的大小低于这个数时,VMM 开始替换页面。它将一直替换页面直到空闲列表的大小达到 maxfree。 
maxfree 
通过 VMM 页面替换空闲列表可达到的最大大小。当进程终止并释放它们的工作段页面或删除其页面在内存中的文件时,结果是空闲列表的大小可能会超过这个数。 
VMM 试图保持空闲列表的大小大于或等于 minfree。当缺页故障或系统需求导致空闲列表大小低于 minfree 时,页面替换算法就开始运行。由于几个原因,空闲列表的大小必须保持在某个级别之上(缺省值是 minfree)。例如,操作系统的顺序预取算法每次需要几个帧用于每个正在进行顺序读取的进程。而且 VMM 必须避免在操作系统自身内部产生死锁,如果没有足够的空间读取需要释放页面帧的页就可能出现这种情况。
下列阈值以百分数的形式表示。它们表示由文件页面(非计算段的页面)占有的机器全部实际内存中的一部分。
minperm 
如果由文件页面占有的实际内存的百分比低于这个级别,则页面替换算法既替换文件页面也替换计算页面,而不管重新调页率。 
maxperm 
如果由文件页面占有的实际内存的百分比高于这个级别,则页面替换算法仅替换文件页面。 
maxclient 
如果由文件页面占有的实际内存的百分比高于这个级别,则页面替换算法仅替换客户机页面。 
当由文件页面占有的实际内存的百分比处于 minperm 和 maxperm 之间时,VMM 通常只替换文件页面,但是如果文件页面的重新调页率高于计算页面的重新调页率的话,计算页面也被替换。
页面替换算法的主要意图是确保计算页面得到合理的待遇。例如,对于可能会很快再次使用的程序文本页,顺序读取长的数据文件到内存中应该不会使它们丢失。对阈值和重新调页率使用页面替换算法可确保合理地对待这两种类型的页面,但仍稍微偏向有利于计算页面的一方。
VMM 内存负载控制工具
进程需要实际内存页面才可以运行。当某进程引用磁盘上的虚拟内存页面时,由于该页要么已经调出要么从未读取过,所以必须调进所引用的页面,而且一般来说,由于必须调出一个或多个页面(如果被替换的页已经做过修改),从而引起 I/O 流量并延迟了进程的进度。
操作系统通过页面替换算法试图从那些最近不可能引用的页面中窃取实际内存。一个成功的页面替换算法允许操作系统在内存中保持足够的进程是活动的,从而保持 CPU 的繁忙。但是在内存竞争的某些级别上,没有较好的候选页面可调出到磁盘上,因为不久之后它们都会由一组活动的进程重用。这种情况取决于下列因素:
·系统中的内存总量 
·处理器数量 
·每个处理器随时间变化的内存需求 
·页面替换算法
出现这种情况时,会出现持续的页面调进和调出。这种情况叫系统颠簸。系统颠簸导致对调页的磁盘进行不断的 I/O 操作,从而导致每个进程几乎一被分派就遇到一个缺页故障,结果是没有一个进程有任何重要的进展。
系统颠簸最具破坏力的方面是,虽然可能是工作负荷中一个短暂而随机的高峰(比如某个系统中所有的用户碰巧在同一秒按下 Enter 键)触发了系统颠簸,但系统可能会持续颠簸不知多长时间。
操作系统有一种内存负载控制算法,它检测系统何时会开始颠簸,然后将活动进程暂挂并将新进程的开始延迟一段时间。有五个参数为该算法设置比率和范围。在一个大的工作负荷范围内,这些参数的缺省值已经选择为“故障安全”。在 AIX V4 中,缺省情况下,内存负载控制在可用内存帧添加到大于或等于 128 MB 的系统上是禁用的。
内存负载控制算法
内存负载控制机制每秒进行一次评估,看是否有足够内存可用于活动的进程组。当检测到内存过量使用的情况时,便暂挂一些进程以减少活动进程的数量,从而降低了内存过量使用的级别。
当一个进程暂挂时,它的所有线程在达到可暂挂状态时也都全部暂挂。暂挂进程的页面立刻变得无效并且由页面替换算法调出,这样释放了足够的页面帧以允许余下的活动进程进行下去。在现有进程暂挂的时间间隔内,新建的进程也暂挂,从而阻止新的工作进入系统。暂挂的进程不会重新激活,直到经过了一段连续的间隔时间且在这个间隔中不会有潜在的系统颠簸情况出现。一旦这个安全间隔时间过去,暂挂进程中的线程便逐步重新激活。
内存负载控制参数指定以下值:
·系统内存过量使用阈值(schedtune -h) 
·所需的安全间隔的秒数(schedtune -w) 
·单独进程的内存过量使用阈值,通过它可将一个单独的进程限定成暂挂候选进程(schedtune -p) 
·当进程暂挂时活动进程的最小数量(schedtune -m) 
·进程重新激活后进行活动所使用的最小秒数(schedtune -e)

对在前面的一秒间隔时间中收集到的所有上述度量值,调度程序(进程 0)每秒进行一次检查,并确定是暂挂进程还是激活进程。如果要暂挂进程,则每个由参数 -p 和 -e 测试出来符合暂挂条件的进程被标记为暂挂。当那个进程接下来在用户方式下接收 CPU 时,就将它挂起(如果不这样做就可能使活动进程数量减少到值 -m 之下)。应用用户方式准则可使在执行关键系统活动期间进程没有资格为自身的利益而挂起。在后继的一秒间隔时间内,如果系统颠簸准则仍然满足,那么满足由 -p 和 -e 设置的条件的额外候选进程被标记成暂挂。如果调度程序后来确定已经满足了安全间隔准则且进程将要重新激活,那么每秒会有一定数量的暂挂进程被放入运行队列(激活)。
决定重新激活暂挂进程的因素:
1. 优先级 
2. 进程被暂挂的顺序
暂挂的进程不能立刻全部重新激活。重新激活进程的数量值由一个公式选择,该公式识别出当时活动进程的数量,然后重新激活该数量的 1/5 的进程或者通过重新激活使活动的进程数在大于下限的基础上单调递增。这个谨慎的策略导致每秒增加了大约 20% 的多程序设计强度。该策略的意图是为了使安全间隔结束后的第一秒内重新激活率相对较低,而在后来的几秒中使重新引入率稳定增加。如果在重新激活进程的过程中再次出现内存过量使用的情况,则会发生下列情况:
·重新激活停止 
·标记为重新激活的进程被再次标记成暂挂 
·根据上述规则有额外进程被暂挂
调页空间槽的分配和回收
操作系统支持对工作存储器(也称为调页空间槽)实行三种分配方法,如下所示:
·后分配 
·预先分配 
·延迟分配
注:调页空间槽仅在进程(不是线程)终止时或由系统调用 disclaim() 释放。槽不能由系统调用 free() 释放。
后分配算法
在具有后分配算法的 AIX 4.3.2 以前的版本中,仅当第一次访问虚拟内存页时才会为该页分配调页槽。就是说正在执行的程序第一次对该页的内容感兴趣。
许多程序使用后分配的途径是为最大的结构分配虚拟内存地址范围然后仅使用和实际情况所需数量一样多的结构。虚拟内存地址范围中从不会访问到的页从来不需要实际内存帧或调页空间槽。
该技术的确包含某种程度的风险。如果所有运行于某机器上的程序正好同时遇到最大需求的情况,调页空间可能会耗尽。这样某些程序就不能继续完成。
预先分配算法
操作系统中第二种调页空间槽分配的方法适于安装的情况,这种情况是一种可能情况或者不能完成的代价可能非常高。该算法称为预先分配是很适当的,它在分配虚拟内存地址范围时就导致分配适当数量的调页空间槽。例如,可通过子例程 malloc() 来实现。如果没有足够的调页空间槽支持子例程 malloc(),就设置一个错误代码。预先分配算法的调用如下:
# export PSALLOC=early
该示例使所有将来在该环境中执行的程序使用预先分配。而当前在运行的 shell 不受影响。
主要因为涉及到预先分配的调页空间的大小,所以性能分析员会对该算法有兴趣。如果为那些程序设置预先分配,那么调页空间需求可能增加许多倍。所以通常推荐调页空间大小至少是系统实际内存的两倍,而对于那些使用 PSALLOC=early 的系统则推荐至少是实际内存大小的四倍。事实上这只是一个起点。还需分析工作负荷的虚拟存储器需求并分配调页空间与其相适应。作为一个例子,如果用预先分配的话,AIXwindows 服务器在运行时一次需要250 MB 的调页空间。
当使用 PSALLOC=early 时,用户应该通过预先分配内存和将内存设置成一个堆栈来为后面的信号 SIGSEGV 设置一个处理程序,设置堆栈用 sigaltstack 函数。即使指定了 PSALLOC=early,如果没有足够的调页空间且程序试图扩展堆栈,则程序可能接收到 SIGSEGV 信号。
延迟分配算法
操作系统调页空间槽分配的第三种方法从 AIX 4.3.2 开始起就缺省为“延迟页面空间分配”(DPSA)策略,它延迟调页空间的分配直到必须调出该页,这样的结果是不会分配无用的调页空间。这种方法能节省大量的调页空间,也意味着磁盘空间的节约。
在一些系统中,即使所有页面的访问都已经发生,但仍有可能不需要调页空间。这种情况在具有超大量 RAM 的系统上很常见。然而,如果访问得较多的是虚拟内存而不是可用的 RAM,这可能导致调页空间的过量使用。
要禁用 DPSA 且保留“后页面空间分配”策略,请运行下列命令:
# /usr/samples/kernel/vmtune -d 0
要激活 DPSA,运行下列命令:
# /usr/samples/kernel/vmtune -d 1

通常,DPSA 可以改善系统性能,因为在缺页故障后避免了分配页面空间的开销。如果使用 DPSA,调页空间设备需要的磁盘空间较少。


转自: http://www-31.ibm.com/support/techdocs/cn/faqhtmlfaq/2611084C28000.htm 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值