当前位置: 首页 > news >正文

网站怎么做能快速有排名网站建设 乐达云创

网站怎么做能快速有排名,网站建设 乐达云创,企业做网站有用吗,免费收录平台系列文章目录 文章目录 系列文章目录3.3 页面的换出MiBalancerThread()MmTrimUserMemory#xff08;#xff09;MmPageOutVirtualMemory#xff08;#xff09; 3.3 页面的换出 在前一节中我们看到#xff0c;如果有映射的页面已经被倒换到磁盘上即倒换文件中#xff0c…系列文章目录 文章目录 系列文章目录3.3 页面的换出MiBalancerThread()MmTrimUserMemoryMmPageOutVirtualMemory 3.3 页面的换出 在前一节中我们看到如果有映射的页面已经被倒换到磁盘上即倒换文件中那么对这个页面的访问就会引起一次缺页异常而相应的异常处理程序就会从磁盘上把这个页面倒换进来。这自然就会产生一个问题:这个页面是在什么时候又是怎样跑到磁盘上去的呢?当然页面(的内容)不会自己跑到磁盘上而得有个行为主体将其倒出到磁盘上这个行为主体就是内核线程MiBalancerThread() . MiBalancerThread() VOID STDCALL MiBalancerThread(PVOID Unused) {PVOID WaitObjects[2];....WaitObjects[0] MiBalancerEvent;//通过Event唤醒WaitObjects[1] MiBalancerTimer;//通过定时器唤醒while (1){Status KeWaitForMultipleObjects(2,WaitObjects,WaitAny,Executive,KernelMode,FALSE,NULL,NULL);if (Status STATUS_SUCCESS){//因为事件而被某个线程唤醒/* MiBalancerEvent */CHECKPOINT;while (MmStats.NrFreePages MiMinimumAvailablePages 5){//循环知道有一个数量的空闲物理页面for (i 0; i MC_MAXIMUM; i){if (MiMemoryConsumers[i].Trim ! NULL){//调用内存消费者的修剪函数NrFreedPages 0;Status MiMemoryConsumers[i].Trim(MiMinimumPagesPerRun, 0, NrFreedPages);if (!NT_SUCCESS(Status)){KEBUGCHECK(0);}}}}InterlockedExchange(MiBalancerWork, 0);CHECKPOINT;}else if (Status STATUS_SUCCESS 1){/* MiBalancerTimer *///因超时而被唤醒ShouldRun MmStats.NrFreePages MiMinimumAvailablePages 5 ? TRUE : FALSE;for (i 0; i MC_MAXIMUM; i)//对于所有的内存消费者{if (MiMemoryConsumers[i].Trim ! NULL){NrPagesUsed MiMemoryConsumers[i].PagesUsed;if (NrPagesUsed MiMemoryConsumers[i].PagesTarget || ShouldRun){//本消费者占用页面数已超过配额或总库存已降到危险点if (NrPagesUsed MiMemoryConsumers[i].PagesTarget){Target max (NrPagesUsed - MiMemoryConsumers[i].PagesTarget,MiMinimumPagesPerRun);}else{Target MiMinimumPagesPerRun;//每次至少修剪的数量}NrFreedPages 0;//执行本消费者的修剪函数Status MiMemoryConsumers[i].Trim(Target, 0, NrFreedPages);if (!NT_SUCCESS(Status)){KEBUGCHECK(0);}}}}}else{//因其他原因被唤醒不应发生DPRINT1(KeWaitForMultipleObjects failed, status %x\n, Status);KEBUGCHECK(0);}} } 这个线程平时都在睡眠但是周期性地通过事件MiBalancerTimer 被定时器唤醒。此外这个线程也可以通过事件 MiBalancerEvent 被唤醒这发生在需要分配物理页面却发现库存不足的时候每当这个线程被唤醒的时候它就借助若干个内存“消费者(Consumer)”的“修剪函数”对内存加以“修剪(Trim)”。所谓修剪就是把一些判断为暂时不会被访问的页面(的内容)倒换出去腾出所占据的物理页面另行分配 如前所述所谓内存“消费者”并不是指实际占用着物理页面的进程而是指各种不同的用途例如用户空间的页面映射内核中的可倒换物理页面池、不可倒换物理页面池磁盘上扇区内容的高速缓存等。内核中有个结构数组MiMemoryConsumers[]其中的每个元素都代表一个“消费者”其下标可以是: #define MC_CACHE (0) #define MC_USER (1) #define MC_PPOOL (2) #define MC_NPPOOL (3) #define MC_MAXIMUM (4)显然,每一种用途即“消费者”都应该提供自己的修剪函数:但是目前ReactOS只为MC_CACHE和MC_USER提供了修剪函数。换言之另两种用途的页面是不让修剪的。其中用户空间页面所映射物理页面的修剪函数为MmTrimUserMemory()。 MmTrimUserMemory [MiBalancerThread()MmTrimUserMemory()]/* FUNCTIONS *****************************************************************/NTSTATUS MmTrimUserMemory(ULONG Target, ULONG Priority, PULONG NrFreedPages) {PFN_TYPE CurrentPage;PFN_TYPE NextPage;NTSTATUS Status;(*NrFreedPages) 0;CurrentPage MmGetLRUFirstUserPage();//运用LRU算法找到第一个可以倒出的页面while (CurrentPage ! 0 Target 0){NextPage MmGetLRUNextUserPage(CurrentPage);//下一个可以倒出的页面//倒出物理页面 CurrentPageStatus MmPageOutPhysicalAddress(CurrentPage);if (NT_SUCCESS(Status)){DPRINT(Succeeded\n);Target--;(*NrFreedPages);}else if (Status STATUS_PAGEFILE_QUOTA)//已超过倒换文件的容量配额{MmSetLRULastPage(CurrentPage);//下次再来}CurrentPage NextPage;}return(STATUS_SUCCESS); } 参数Target是要求修剪的页面数量,NrFreedPages用来返回实际修剪的数量,另一个参数Priority实际上没有被用到。 修剪的对象是“最近最少被用到”的页面相应的算法为LRU。与MiMemoryConsumers[]平行,内核中还有个队列头数组 UsedPageListHeads[]也是以 MC_USER 等为下标凡是被分配用于某个消费者的物理页面其数据结构都按LRU的次序挂在其队列中。LRU是一种常用的算法我们就不深入到这里面去了。 找到修剪对象的物理页面号之后就通过MmPageOutPhysicalAddressO)将其倒换出去。 MmPageOutVirtualMemory [MiBalancerThread() MmTrimUserMemory() MmPageOutPhysicalAddress()MmPageOutVirtualMemory()]NTSTATUS NTAPI MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,PMEMORY_AREA MemoryArea,PVOID Address,PMM_PAGEOP PageOp) {PFN_TYPE Page;BOOLEAN WasDirty;SWAPENTRY SwapEntry;NTSTATUS Status;DPRINT(MmPageOutVirtualMemory(Address 0x%.8X) PID %d\n,Address, AddressSpace-Process-UniqueProcessId);/** Check for paging out from a deleted virtual memory area.*/if (MemoryArea-DeleteInProgress){PageOp-Status STATUS_UNSUCCESSFUL;KeSetEvent(PageOp-CompletionEvent, IO_NO_INCREMENT, FALSE);MmReleasePageOp(PageOp);return(STATUS_UNSUCCESSFUL);}/** Disable the virtual mapping.//关断目标页面的映射*/MmDisableVirtualMapping(AddressSpace-Process, Address,WasDirty, Page);if (Page 0){KEBUGCHECK(0);}/** Paging out non-dirty data is easy.*/if (!WasDirty){//页面是干净的物理页面空白或其内容与倒换文件中的对应页面完全相同MmLockAddressSpace(AddressSpace);MmDeleteVirtualMapping(AddressSpace-Process, Address, FALSE, NULL, NULL);MmDeleteAllRmaps(Page, NULL, NULL);if ((SwapEntry MmGetSavedSwapEntryPage(Page)) ! 0){MmCreatePageFileMapping(AddressSpace-Process, Address, SwapEntry);MmSetSavedSwapEntryPage(Page, 0);}MmUnlockAddressSpace(AddressSpace);MmReleasePageMemoryConsumer(MC_USER, Page);PageOp-Status STATUS_SUCCESS;KeSetEvent(PageOp-CompletionEvent, IO_NO_INCREMENT, FALSE);MmReleasePageOp(PageOp);return(STATUS_SUCCESS);}/** If necessary, allocate an entry in the paging file for this page*/SwapEntry MmGetSavedSwapEntryPage(Page);if (SwapEntry 0){SwapEntry MmAllocSwapPage();if (SwapEntry 0){MmShowOutOfSpaceMessagePagingFile();MmEnableVirtualMapping(AddressSpace-Process, Address);PageOp-Status STATUS_UNSUCCESSFUL;KeSetEvent(PageOp-CompletionEvent, IO_NO_INCREMENT, FALSE);MmReleasePageOp(PageOp);return(STATUS_PAGEFILE_QUOTA);}}/** Write the page to the pagefile*/Status MmWriteToSwapPage(SwapEntry, Page);if (!NT_SUCCESS(Status)){DPRINT1(MM: Failed to write to swap page (Status was 0x%.8X)\n,Status);MmEnableVirtualMapping(AddressSpace-Process, Address);PageOp-Status STATUS_UNSUCCESSFUL;KeSetEvent(PageOp-CompletionEvent, IO_NO_INCREMENT, FALSE);MmReleasePageOp(PageOp);return(STATUS_UNSUCCESSFUL);}/** Otherwise we have succeeded, free the page*/DPRINT(MM: Swapped out virtual memory page 0x%.8X!\n, Page PAGE_SHIFT);MmLockAddressSpace(AddressSpace);MmDeleteVirtualMapping(AddressSpace-Process, Address, FALSE, NULL, NULL);MmCreatePageFileMapping(AddressSpace-Process, Address, SwapEntry);MmUnlockAddressSpace(AddressSpace);MmDeleteAllRmaps(Page, NULL, NULL);MmSetSavedSwapEntryPage(Page, 0);MmReleasePageMemoryConsumer(MC_USER, Page);PageOp-Status STATUS_SUCCESS;KeSetEvent(PageOp-CompletionEvent, IO_NO_INCREMENT, FALSE);MmReleasePageOp(PageOp);return(STATUS_SUCCESS); } 需要倒换出去的页面可能是“干净”的也可能是“脏”的。 所谓干净的页面是指自从上一次建立通向这个物理页面的映射以来从未对其进行过写操作的面具体有两种可能: 1,这是个刚被分配并建立映射但从未被写过的空白页面。这样的页面在倒换文件中尚无对应的倒换页面也不需要有因为以后需要时可以重新分配一个空白页面。所以只要删除其映射并通过 MmDeleteAlRmaps()使其与所属的进程脱钩最后释放这个物理页面就可以了 2,这是个从倒换文件换入的页面但是换入之后从未被写过。这样的页面在倒换文件中已经有了对应的倒换页面但是不需要改变倒换页面的内容。对于这样的页面一方面要删除其映射另一方面要使相应的页面映射表项指向倒换文件中的页面。凡是有了倒换页面的物理页面其PHYSICAL PAGE结构中的SavedSwapEntry字段就指向这个倒换页面现在一方面将该字段的内容转移到相应的页面映射表项中(并将其PAPRESENT标志位清0)另一方面通过 MmSetSavedSwapEntryPage()将这个字段清 0。然后再释放这个物理页面。 倒换页面是由“倒换页面项”SWAPENTRY描述的这是个32位无符号整数实际上是倒换文件号与文件内页面号的组合 所谓脏的页面则是指自从上一次建立通向这个物理页面的映射以来已经对其进行过写操作的面具体又有两种可能: 1,这本是个刚被分配并建立映射的空白页面但是现在已经不再空白。这样的页面在倒换文件中尚无对应的倒换页面但是需要有。所以通过MmAllocSwapPageO)分配一个倒换页面这个函数返回一个SWAPENTRY说明是哪一个倒换文件中的哪一个页面。然后通过MmWriteToSwapPage()将页面的内容写入倒换文件,再将相应的页面映射表项改成指向倒换页面(并将其 PA_PRESENT标志位清0)最后释放该物理页面。 2,这是个从倒换文件换入的页面但是换入之后已经被写过。这样的页面在倒换文件中已经有了对应的倒换页面但需要改变其内容。所以也由MmWriteToSwapPageO)将页面的内容写入倒换文件再将相应的页面映射表项改成指向倒换页面(并将其PA_PRESENT标志位清 0)最后释放该物理页面。 至于 MmWriteToSwapPage()则已经属于文件操作的范畴这里就不深入下去了。最后再概括一下倒换页面与物理内存页 面和页面映射表项PTE之间的关系: 1,如果(虚存)页面的内容在物理页面中则相应的PTE指向该物理内存页面而物理内存页面的 PHYSICAL_PAGE结构中的SavedSwapEntry 字段指向作为后备的倒换页面。 2,如果(虚存)页面的内容不在物理页面中则相应的PTE直接指向倒换页面。
http://www.dnsts.com.cn/news/167162.html

相关文章:

  • seo 对网站有什么影响wordpress主题博客
  • 瀑布流网站医院网站队伍建设
  • 搜关键词可以搜到的网站怎么做万界商城系统
  • 国际网站群建设方案计算机网页设计专业学什么
  • 化妆品购物网站建设目的平面电商设计是什么
  • 怎么为自己公司做网站wordpress 爱主题
  • 深圳建设工程交易网站宝安电子商务网站建设评估工具
  • 网站标题图片怎么做wordpress伪静态规则文件
  • 做游戏网站官方网站建设调研报告
  • 百度做的网站字体侵权河北建设集团园林网站
  • wordpress 添加友情链接昆明seo关键词排名
  • 局域网网站建设需要什么条件昆山高端网站建设公司
  • 苏州网站建设外贸济南做网站公司排名
  • 网站营销费用免费高清视频软件
  • 淘宝网站怎么做的好福田官网
  • 深圳做网站排名哪家专业景区旅游门户网站建设方案
  • 铁岭网站开发网站建设公司宣传标语
  • 韶关市建设局官方网站濮阳市做网站
  • discuz 网站搬家世界500强企业分布
  • 注册网站什么要求下载网站php源码
  • 建设银行的网站是多少钱wordpress页面分页
  • 东莞seo网站关键词优优化单页网站怎么制作
  • 成都网站设计报告书wordpress怎么调用分类的文章
  • 建网站权威公司网站 的版面结构
  • 网站制作和优化有网站开发专业吗
  • 深圳网站建设V芯ee8888e深圳专业网站建设免费送域名空间
  • 免费注册个人网站网站开发 制作
  • 公司网站建设比较好的公司西昌规划和建设局网站
  • 欧美网站建设风格特点网上开店的货源渠道有哪些
  • 网络优化网站 site网站开发项目实例