深入解析Windows操作系统(笔记7)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/flukeshen/article/details/86531146

  32位的应用程序,开启大地址空间标志的情况下,在64位Windows系统可用4GB的内存空间(32位系统上最多达3G)。

  内存管理器是Windows执行体的一部分(位于Ntoskrnl.exe中),主要由:
  一组执行体系统服务,负责分配、释放和管理虚拟内存;
  提供内存管理异常中的,转译无效陷阱处理器,以及访问错误陷阱处理器;
  工作集管理器(优先级16),驻留在物理内存的部分称作工作集;
  进程/栈交换器(优先级23),执行进程栈和内核线程栈换入换出操作;
  已修改页面写出器(优先级17),将修改列表上的脏页面写回到页面文件中;
  映射页面写出器(优先级17),将映射文件中的脏页面写到磁盘上;
  解引用段线程(dereference segment thread,优先级18),负责页面缓存的减少;
  零页面线程(优先级0),将空闲列表上的页面清零。

  内存管理器必须同步访问全局资源包括页面帧编号(PFN,page frame number)数据库(通过自旋锁)、内存区对象和系统工作集(通过压栈锁),以及页面文件的创建(通过互斥体)。

  应用程序的保留地址区域按64KB对齐。已提交的虚拟页面在第一次访问的时候才真正被创建起来,并且页面初始化为零(demand zero)。

 应用程序可以调用VirtualLock函数来锁住进程工作集页面在物理内存中,驱动程序可以调用MmProbeAndLockPages、MmLockPagableCodeSection、MmLockPagableDataSection或MmLockPagableSectionByHandle来锁住页面。

  内存区对象可以被连接到磁盘上的文件(映射文件),或连接到提交的内存(共享内存)。

  前端堆类型:
  预读列表(Look-Aside List),预读列表是一个单向列表,列表按照后进先出(LIFO)的顺序和非阻塞的方式来操作。
  低碎片堆(LFH,Low Fragmentation Heap),显示调用函数HeapSetInformation以后,LFH才被打开。
  进程在调试状态下,堆调试选项被打开,此时前端堆被禁止,改而使用核心堆。

  转译虚拟地址过程:
  一个虚拟地址,高10位是页目录索引,中间10位是页表索引,低12位是页内偏移。
  1.内存管理硬件找到当前进程的页目录(CR3寄存器保存着当前进程页目录的物理地址);
  2.利用页目录索引找到相应的页目录项(PDE),PDE包含了页表的页面帧编号(PFN,page frame number),注意页表时可以被换出的;
  3.利用页表索引找到相应的页表项(PTE),PTE包含了目标页的物理地址;
  4.如果PTE是有效的,则解释为PFN找到物理页面,如果PTE是无效的,交由内存管理错误处理器(fault handler),试图变为有效页面(尝试失败产生错误异常);
  5.利用页内偏移,找到目标数据。

  每个进程都有一个页目录(page directory),页目录的物理地址保存在内核进程块(KPROCESS)中,其虚拟地址映射在0xC030000处,每次发生进程环境切换,内核将页目录位置从KPROCESS结构中加载到CR3寄存器。
  页目录中的每一项(PDE,page direcotry entry)是4字节长,页目录描述了该进程所有可能的页表状态和位置,页表是按需创建的。页表中的每一项(PTE)高20位是页面帧编号(PFN),低12位是一些标志属性值,其中位0代表此PTE是否有效,引用无效的PTE称为页面错误(page fault),内核陷阱处理器把这种错误分发给内存管理器的错误处理器(fault hanlder,MmAccessFault),此时PTE高20位解释为页面文件偏移。

  虚拟地址描述符(VAD,virtual address descriptor),对每个进程内存管理器都维护了一组VAD来描述该进程地址空间状态,这些VAD组织成一棵自平衡二叉树。

  内存区对象(section object),代表多个进程可以共享的一块内存,Windows子系统将其称为文件映射对象(file mapping object)。内存区对象可以被映射到页面文件中,也可以映射到磁盘上的其他文件中。

  XP中加入的逻辑预取器(logical prefercher),可以加速引导过程和应用程序启动过程,内存管理器会将页面错误通知给内核中的预取器,预取器记录下这些信息(对于应用程序监视启动过程的前10秒,对于引导过程监视自系统启动开始至用户外壳Explorer启动之后的30秒),当下一次系统引导或应用程序启动的时候,调用预取器提前载入这些页面,而且在系统空闲的时候,任务调度器还会把这些预取页面的文件,按先后顺序通过碎片整理器,在磁盘物理上也是连续存放,更加优化整个过程。

  虚拟页面在换出时,常见的置换策略有最近最少使用(LRU,least recently used)策略和先进先出(FIFO,first in first out)策略,置换策略可进一步被归结为全局或局部的,比如这个页面是否只能被所属进程置换等。

展开阅读全文

没有更多推荐了,返回首页