Windows内存管理学习笔记(三)—— 无处不在的缺页异常

  • 缺页异常
    • 实验一:设置虚拟内存
  • 无处不在的缺页
    • 位于页面文件
    • 保留与提交的误区
    • 实验二:理解缺页异常
    • EXECUTE_WRITECOPY

缺页异常

描述

  1. 例:当CPU访问一个地址,其PTE的P位(页面有效位)为0,此时会产生缺页异常
  2. 在windows中,缺页异常是时刻在发生的

PTE结构(10-10-12分页)

假设:当我们的物理内存大小只有2MB时,当我们需要用到某个物理页的时候,将对应物理页的P位置1,当我们不再需要使用该物理页时,再将其P位置0,这样的内存使用效率是非常低的,因此windows不是这样设计的——只有正在使用的线性地址,才会被挂上物理页,当物理页在一段时间内不被使用或不够用的情况下,操作系统会将当前物理页中的数据拷贝至硬盘中,然后将当前物理页供给“别人”使用,当需要再次用到该物理页的数据时,则将“别人”的数据再拷贝出来,将“自己"的数据从硬盘中拷回,被拷至硬盘中的物理页数据会被写入到一个文件中,也就是我们平时常说的虚拟内存

实验一:设置虚拟内存

1)右键”我的电脑“-属性-高级-”性能“设置-高级
2)将虚拟内存大小设置为780MB

3)查看c:\pagefile.sys文件属性(需设置文件夹选项-显示隐藏文件)

当物理页占用情况较为紧张时,这个文件用于存放物理页的临时数据作为备份

无处不在的缺页

描述:当线性地址对应的物理页被存储到文件中时,PTE结构被拓展为以下四种情形

位于页面文件

描述

  1. 当物理页被放入页面文件时,PTE结构如图a所示
  2. 当该进程再次读取该物理页对应的线性地址时,由于P位为0,因此会触发缺页异常处理程序
  3. windows xp中,缺页异常处理程序位于IDT[0xE]
  4. 此时,缺页异常处理程序会再次查询当前PTE的属性,若1-4位,5-9位,12-31位都有值,说明当前PTE是有效的,但是物理页被存放到了页面文件中
  5. 然后,缺页异常处理程序根据PTE中得到的值去查询pagefile.sys,将原来的物理页的内容挂入新的物理页,然后将P位置1,再将新的物理页的物理地址挂入PTE的第12-31位
  6. 在用户看来,两次读取同一个线性地址,中间这一系列复杂过程是透明的,而只能观察到两次都成功读取了同一个值

保留与提交的误区

我们对于VirtualAlloc的传统概念

LPVOID VirtualAlloc{LPVOID lpAddress,DWORD dwSize,DWORD flAllocationType,    // 分配的类型// MEM_RESERVE:只保留线性地址,不分配物理页// MEM_COMMIT:既保留线性地址,又分配物理页DWORD flProtect
};

思考:如果设置flAllocationType成员的值为MEM_COMMIT,当函数执行结束之后,马上就会为当前线性地址分配物理页吗?
答案:不会,只有当线性地址真正被使用时,才会分配物理页

实验二:理解缺页异常

1)编译并运行以下代码

#include <stdio.h>
#include <windows.h>int main()
{LPVOID pAddr = VirtualAlloc(NULL, 0x1000*8, MEM_COMMIT, PAGE_READWRITE);printf("%p\n", pAddr);getchar();*(PDWORD)pAddr = 0x12345678;getchar();return 0;
}

2)运行结果

3)查看pAddr所在的线性地址是否存在物理页

kd> !process 0 0




可以看到,此时并未被挂上具体物理页(PTE为空)

备注:上述步骤也可以使用以下命令进行代替

4)继续运行程序,再次查看PTE


此时线性地址被挂上物理页(PTE有值)

5)观察VadRoot

标红行的8指的是最多可以为这块线性地址分配8个物理页(0-7),但不是每块线性地址都已被挂上有效的物理页,只有当对应线性地址块被使用时,才会真正被挂上物理页

6)观察_MMVAD结构体

当访问一个未被挂上物理页的线性地址时,会触发缺页异常,缺页异常处理程序会去查找VadRoot,若当前线性地址已被分配,则会将其挂上物理页,否则会触发内存访问错误

总结:缺页异常使得物理页的使用更加高效

EXECUTE_WRITECOPY

描述:当程序正常加载一个EXE或者DLL时,其VadRoot中的内存属性为Mapped EXE,权限为EXECUTE_WRITECOPY,当试图对其某一内容进行修改时,无法对其它进程中的同一个模块产生影响

原理

  1. 当试图对其某一内容进行修改时,系统会检查其线性地址对应的物理页的PTE属性,若R/W属性为0时,触发缺页异常
  2. 缺页异常处理程序检查VadRoot中对应线性地址所在空间的MMVAD_FLAGS中的Protection成员,若值位0x111时,表示权限为EXECUTE_WRITECOPY
  3. 此时,缺页异常处理程序将当前线性地址对应的物理页内容进行拷贝,将其写入一个新的物理页,然后将当前进程需要修改的线性地址挂入新的物理页上,然后对需要修改的内容进行写入

解决方法:可通过编写驱动程序先将需要修改的线性地址对应的物理页的PTER/W位置为1,再对需要修改的地方进行修改

Windows内存管理学习笔记(三)—— 无处不在的缺页异常相关推荐

  1. Windows内存管理学习笔记(二)—— 物理内存的管理

    Windows内存管理学习笔记(二)-- 物理内存的管理 物理内存 实验一:理解MmNumberOfPhysicalPages MmPfnDatabase _MMPFN 物理页状态 六个链表 实验二: ...

  2. Windows内存管理学习笔记(一)—— 线性地址的管理

    Windows内存管理学习笔记(一)-- 线性地址的管理 用户空间线性地址的管理 实验一:理解用户空间线性地址管理 Private Memory 实验二:理解Private Memory 堆 实验三: ...

  3. 郝健: Linux内存管理学习笔记-第4节课

    前序文章: 郝健: Linux内存管理学习笔记-第1节课 郝健: Linux内存管理学习笔记-第2节课 郝健: Linux内存管理学习笔记-第3节课 摘要 page cache free命令的详细解释 ...

  4. 郝健: Linux内存管理学习笔记-第5节课

    前序文章: 郝健: Linux内存管理学习笔记-第1节课 郝健: Linux内存管理学习笔记-第2节课 郝健: Linux内存管理学习笔记-第3节课 郝健: Linux内存管理学习笔记-第4节课 摘要 ...

  5. 郝健: Linux内存管理学习笔记-第6节课

    前序文章: 郝健: Linux内存管理学习笔记-第1节课 郝健: Linux内存管理学习笔记-第2节课 郝健: Linux内存管理学习笔记-第3节课 郝健: Linux内存管理学习笔记-第4节课 郝健 ...

  6. 郝健: Linux内存管理学习笔记-第3节课

    摘要 进程的虚拟地址空间VMA(Virtual Memory Area) Pagefault的几种可能性.VMA的作用.major缺页和minor缺页 进程内存消耗的4个概念:vss.rss.pss和 ...

  7. 郝健: Linux内存管理学习笔记-第2节课

    摘要 slab./proc/slabinfo和slabtop 用户空间malloc/free.内核空间kmalloc/kfee与Buddy的关系 mallopt vmalloc Linux为应用程序分 ...

  8. 郝健: Linux内存管理学习笔记-第1节课【转】

    本文转载自:https://blog.csdn.net/juS3Ve/article/details/80035751 摘要 MMU与分页机制 内存区域(内存分ZONE) LinuxBuddy分配算法 ...

  9. 郝健: Linux内存管理学习笔记-第1节课

    摘要 MMU与分页机制 内存区域(内存分ZONE) LinuxBuddy分配算法 CMA(连续内存分配器) 0.    课前阅读 宋宝华:CPU是如何访问到内存的?--MMU最基本原理 http:// ...

最新文章

  1. 鸿蒙系统支持最低处理器,这四款华为手机可升级到鸿蒙系统,老机型居多,最低只需千元!...
  2. python从1到n出现了多少个1-Python解决 从1到n整数中1出现的次数
  3. JavaScript基础04【逻辑、复制、关系、相等运算符、Unicode编码表】
  4. poj 2390 Bank Interest(计算本利和)
  5. 师范生计算机硬件技能怎么填,浅析对师范生教育技术能力培养与发展问题的思考的论文...
  6. 安徽计算机对口大学有哪些专业,计算机专业对口升学安徽院校
  7. 翻译 - 【Dojo Tutorials】Getting Started with dojox/app
  8. 3.Linux性能诊断 --- 快速检查单(10个命令) 监控
  9. springmvc 使用
  10. BP神经网络的预测模型
  11. JavaScript开发必备!这四款静态代码分析工具你了解吗?
  12. 【生物信息学】ATAC-seq流程及代码分析、复现文章
  13. python实现广义线性模型
  14. Delphi程序破解技术概要
  15. Python中文文本分句 sentence tokenize
  16. 牛顿法及其下山法+C代码
  17. 12、Zabbix 结合Grafana
  18. 移民就移民了,别拉祖国来垫背
  19. uniapp提示系统已存在更高版本
  20. manifest java_JAR包中的MANIFEST.MF文件详解以及编写规范

热门文章

  1. 成功解决TypeError: drop() missing 1 required positional argument: 'labels'
  2. Py之pydotplus:pydotplus的简介、安装、使用方法之详细攻略
  3. IDE之Eric:Python的IDE之eric的简介、安装、使用方法之详细攻略
  4. 人工智能的时代?未来已至?
  5. 盘点selenium phantomJS使用的坑
  6. 我的Python分析成长之路4
  7. sql 获取本周周一和周日
  8. C#创建带参数的线程
  9. c++ template笔记(2)模板类
  10. [ZZ88]送给即将毕业奔三的男人们的16条忠告