Windows驱动开发基础(八)内存管理

Windows驱动开发基础系列,转载请标明出处:http://blog.csdn.net/ikerpeng/article/details/38826159


就32位的计算机来说,他有4G的真实的物理内存。但是这样是不够的,于是引入了虚拟内存的概念。使得每一个进程都有4G的虚拟内存。


虚拟内存实际上就是采用了一种映射的方式。4G的内存实际上被分页。一般来说一个页的大小是4K。也是说它被分为了1M个页。在这么多的页里面,有一部分是对应于物理内存的(可以是多对一的);有一部分是对应于磁盘上的空间,但是这部分的数据会被标记为(Dirty);还有一部分是空的!

                        Windows驱动开发基础(八)内存管理_第1张图片

没找到太合适的图哈。

     虚拟的内存中低2G被称为用户模式地址;高位的2G被称为内核模式地址。所有进程的内核地址映射完全一致,进程切换的时候,只要改变用户模式地址的映射。


    Windows驱动程序使用的内存资源非常珍贵,分配内存时要尽量节约。和应用程序一样,局部变量是存放在栈空间中的。但栈空间不会像应用程序那么大,所以驱动程序不适合递归调用或者局部变量是大型数据结构。如果需要大型数据结构,我们可以在堆中申请。


Windows规定有些有些虚拟内存页面是可以交换到文件中的,这类的内存被称为分页内存;反之不能的被称为:非分页内存。

当程序的中断请求在DISPATCH_LEVEL或之上的时候,程序只能使用非分页内存,否则就会出现蓝屏死机


Windows驱动中使用的链表:

对于单链表,每一个元素中的Next指向下一个元素;对于双链表,每一个元素中有两个指针:BLINK指向前一个元素, FLINK 指向后一个元素. 初始化的时候指向自己。如图所示:

                                       Windows驱动开发基础(八)内存管理_第2张图片

我们看看他的结构体:

typedef struct _LIST_ENTRY {
  struct _LIST_ENTRY *Flink;
  struct _LIST_ENTRY *Blink;
} LIST_ENTRY, *PLIST_ENTRY;

里面没有定义数据,需要程序猿自己定义每一个数据的类型。

例如:

typedef struct _MYDATASTRUCT{

LIST_ENTRY  ListEntry;

ULONG  x;

ULONG  y;

}MYDATASTRUCT,*PMYDATASTRUCT;


在我们对于内存的操作过程中,如果频繁的申请内存,会出现:空洞问题,也就是我们的磁盘碎片。为了避免这个问题,驱动程序中使用Lookaside结构来处理。他就像是一个内存容器,先向Windows申请了一块比较大的内存区域,然后自己可以智能的避免产生空洞的情况。


运行时函数:一般来说是以Rtl开头的,是程序运行时必不可少的。包括:内存间复制(可重叠,不可重叠),填充内存,内存比较等。


本小节完!


参考文献:

《 Windows 驱动开发技术详解 》


你可能感兴趣的:(C++,window编程)