
自从本书的上一版本发布以来,Windows操作系统在升级和概念更改方面已经走了很长一段路要走,这导致了Windows 10内核的新稳定体系结构。
《 Windows Internal Device》一书是为希望了解Windows 10主要组件的内部生命的专业人员而创建的。基于此信息,开发人员可以通过为Windows平台创建应用程序并解决与其操作相关的复杂问题,更容易找到正确的设计解决方案。 系统管理员只要知道操作系统底层的内容,便能够了解系统的行为,并迅速解决提高生产率和诊断故障的问题。 安全专业人员将需要有关处理操作系统漏洞的信息。
页面列表动态
在图。 图5.37显示了页块转换的状态图。 为简单起见,它不提供已修改但不可记录的页面的列表。
页面块以下列方式在页面列表之间移动。
1.当内存管理器需要用零填充的页面来处理与重置页面的要求有关的页面错误(访问定义为完全用零填充的页面,或者访问尚未确认的已关闭的确认用户模式页面)时,首先尝试从此类页面列表中获取此页面。 如果列表为空,则该页面将从可用页面列表中获取并填充零。 如果空闲页面列表为空,则访问等待页面列表,并且该列表中的页面用零填充。
2.要求填充零的页面的原因之一是要满足各种安全要求,例如,通用标准(Common Criteria)。 一般标准的大多数规定表明,用户模式进程应接收置零的页块,以便它们无法读取以前进程的内存内容。 因此,除非已从备份存储中读取页面,否则内存管理器为用户模式进程提供无效的页面块。 在这种情况下,内存管理器将使用非重置页块,并使用磁盘或远程存储中的数据对其进行初始化。 填充零的页面列表将从空闲页面列表中补充一个称为零页面线程的系统程序线程-这是系统进程中的线程0。 页面清零流正在等待网关对象发出的信号。 当空闲列表中有八个或更多页面时,网关将发出蜂鸣声。 但是只有在至少一个处理器没有其他可执行线程的情况下才启动页面清零线程,因为页面清零线程以优先级0开始,并且可以为用户流设置的最低优先级为1。
注意当由于调用MmAllocatePagesForMdl或MmAllocatePagesForMdlEx函数的驱动程序分配物理页面而导致的内存必须由Windows应用程序调用AllocateUserPhysicalPages或AllocateUserPhysicalPagesNuma函数填充零时,或者当应用程序分配使用内存管理器来使用内存功能的大页面时,内存为空与页面清零流相比,显示的区域更大,一次仅重置一页。 此外,在多处理器系统上,内存管理器会创建一个额外的系统线程,以在并行模式下进行调零(在NUMA平台上,这是针对NUMA技术优化的样式来完成的)。
3.当内存管理器不需要用零填充的页面时,他首先访问空闲页面列表。 如果该列表为空,则转到归零页面列表。 如果清零页面列表为空,则转到待处理页面列表。 在内存管理器可以使用等待页面列表中的页面块之前,他必须首先返回并从仍然指向该页面块的无效PTE记录(或原型PTE记录)中删除该链接。 由于PFN编号数据库条目包含指向用户页面表的上一页(或指向共享页面的原型PTE条目池页面)的后向指针,因此内存管理器可以快速找到PTE条目并进行相应的更改。
4.当某个进程必须从其工作集中放弃某个页面时(要么是因为它引用了一个新页面并且其工作集已满,要么是因为内存管理器削减了它的工作集),如果该页面保持不变,则会进入等待列表(未更改),或者如果已在物理内存中更改了页面,则转到已更改页面的列表。
5.该过程完成后,所有关闭的页面都将进入空闲页面列表。 此外,如果在关闭指向页面文件支持的部分的最后一个链接时,该部分没有任何显示的视图,则该部分的页面也将落入空闲页面列表中。
实验:查看免费页面和零页面
可以在Process Explorer的System Information窗口中查看流程结束时关闭页面的释放。 首先,您需要创建一个在其工作集中包含许多关闭页面的流程。 我们已经在前面的一个实验中使用TestLimit实用程序进行了此操作:
C:\Tools\Sysinternals>Testlimit.exe -d 1 -c 1500 Testlimit v5.24 - test Windows limits Copyright (C) 2012-2015 Mark Russinovich Sysinternals - www.sysinternals.com Process ID: 13928 Leaking private bytes with touch 1 MB at a time... Leaked 1500 MB of private memory (1500 MB total leaked). Lasterror: 0 The operation completed successfully.
–d开关使TestLimit不仅选择已关闭并确认的内存,还“触摸”它,即访问该内存。 这将导致分配物理内存并将其分配给进程,以释放已关闭的已确认虚拟内存的区域。 如果系统有足够的可用RAM,那么将为RAM中的进程分配最多1,500 MB。 现在,此过程将一直等到您强迫它完成或中断工作(可能使用其命令窗口中的组合键Ctrl + C)。 请按照下列步骤。
1.打开进程资源管理器。
2.选择查看系统信息命令,然后选择内存选项卡。
3.观察免费(零)和免费(零)页面列表的大小。
4.终止或中止TestLimit进程。
您也许可以看到空闲页面列表的大小已短暂增加。 我们之所以说“可能”是因为页面清零流将在被清零页面列表中只有8个条目时立即“唤醒”,并且将非常快速地工作。 Process Explorer每秒仅刷新一次此窗口,似乎其他页面已经有时间重置到重置页面列表,而我们设法“捕获”了此状态。 如果您设法注意到空闲页面列表中的临时增加,那么在此之后,您会发现其大小将减小为零,并且在清零页面列表中也会发生相应的增加。 如果错过了片刻,您只会看到归零页面列表中的数字有所增加。
实验:查看已更改和预期页面的列表
使用Sysinternals软件包或内核调试器中的VMMap和RAMMap程序,可以观察到将页面从进程的工作集移动到已修改页面的列表,然后再移动到等待页面的列表。 请按照下列步骤。
1.运行RAMMap程序并观察系统的稳定状态。 在这种情况下,它是具有3 GB RAM的x86系统。 窗口中的列反映了页面的不同状态(见图5.37)。 为了方便起见,一些与该实验无关的列已经缩小。
2.系统具有约420 MB的可用RAM(由可用页面和清零页面组成)。 等待页面列表中将显示大约580 MB(因此,其中一些“可用”,但最有可能包含以前由进程丢失或用于超取的数据)。 大约有830 MB处于活动状态,并通过有效的页表项直接映射到虚拟地址。
3.根据页面的使用或来源(封闭的过程页面,显示的文件等)的状态,进一步细分每一行。 例如,在活动的830 MB时,由于该进程的关闭页面的分配,大约有400 MB。
4.现在,与前面的实验一样,使用TestLimit实用程序创建一个工作集中包含大量页面的流程。 再一次,我们使用–d开关强制TestLimit写入每个页面,但是这次(但不限于此)创建尽可能多的关闭的修改页面:
C:\Tools\Sysinternals>Testlimit.exe -d Testlimit v5.24 - test Windows limits Copyright (C) 2012-2015 Mark Russinovich Sysinternals - www.sysinternals.com Process ID: 7548 Leaking private bytes with touch (MB)... Leaked 1975 MB of private memory (1975 MB total leaked). Lasterror: 8
5.现在,TestLimit已创建1975个分配区域,每个分配区域1 MB。 要更新RAMMap中的屏幕,您需要使用FileRefresh命令来更新屏幕,因为RAMMap不会自行执行此操作(由于此操作的成本很高)。
6.如您所见,活动的2.8 GB以上,其中2.4 GB处于关闭的进程页面行(“进程专用”行)中。 这是分配内存并从TestLimit进程访问它的结果。 还请注意,“待机”,“清零”和“空闲”页面的列表现在要小得多。 分配给TestLimit的大部分内存来自这些列表中列出的页面。
7.接下来,使用RAMMap,您需要评估进程物理页的分配。 转到“物理页面”选项卡,然后在“处理”列的底部设置过滤器,将其设置为Testlimit.exe。 下一个窗口显示了该流程工作集中的所有物理页面。
8.我们需要确定物理地址空间分配中涉及的物理页面,这是在启动TestLimit程序时使用-d开关执行的。 由于来自RAMMap函数VirtualAlloc的调用,RAMMap没有给出任何分配虚拟区域的指示。 但是我们可以使用VMMap程序获得有关此主题的宝贵提示。 通过调用VMMap
通过相同的过程,我们得到以下结果(请参见上面第535页的图)。
9.在显示的信息的底部,有数百个已分配区域用于关闭的过程数据,每个区域的大小为1 MB,其中已确认的内存为1 MB。 这对应于TestLimit分配的内存大小。 上一个截屏突出显示了这些分发选项中的第一个。 请注意,其起始虚拟地址为0x310000。
10.现在返回到RAMMap程序在屏幕上显示的有关物理内存的信息。 重新排列各列,以使“虚拟地址”列清晰可见。 单击它以该值对行进行排序,然后您可以找到所需的虚拟地址(请参见下面的第535页的图)。
11.这里显示了从地址0x310000开始的虚拟页面当前已映射到物理地址0x212D1000。 使用-d开关,TestLimit会将其名称写入每个所选区域的前几个字节。 这可以使用本地内核调试器的!Dc命令来演示(dc代表“显示字符”,即,将字符输出到物理地址):
lkd> !dc 0x212d1000 #212d1000 74736554 696d694c 00000074 00000000 TestLimit....... #212d1010 00000000 00000000 00000000 00000000 ................ ...
12.如果您延迟,则尝试可能会失败-该页面可能已从工作集中删除。 在实验的最后阶段,我们将显示在减少流程的工作集之后,数据保持不变(至少一段时间),并且页面首先移至已更改列表,然后移至等待页面。
13.在VMMap程序中选择TestLimit进程后,打开“查看”菜单,然后选择“清空工作集”命令以最小化该进程的工作集。 现在,在VMMap窗口中,应显示以下信息:
14.请注意,工作集行几乎为空。 该过程的中间部分显示工作集的总大小仅为4 KB,几乎所有空间都由页表占用。 现在回到RAMMap。 在“使用计数”选项卡上,您可以看到活动页面的数量已大大减少,更改列表中有大量页面,而等待列表中有大量页面。
15. RAMMap的“进程”选项卡上的数据确认由于TestLimit进程,这些页面中的大多数出现在这些列表中。
»这本书的更多信息可以
在出版商的网站上找到»
目录»
摘录Windows优惠券20%的折扣
-Windows