非分页内存是虚拟内存吗?
非分页内存是虚拟内存吗?分页内存和非分页内存区别是什么?下面是小编给大家整理的一些相关知识,希望对大家有帮助!
非分页内存是虚拟内存吗?
在写驱动的时候,经常要调用ExAllocatePoolWithTag函数分配内存,其中第一个参数可以是如下几个:
其中,主要的两个区别就是分页内存和非分页内存。
分页内存是低中断级别的例程可以访问的。
而非分页内存则是各个中断级别的例程都可以使用的。
区别在于:
分页内存是虚拟内存,在物理上未必总是能得到。
操作系统实现虚拟内存的主要方法就是通过分页机制。在Win32中,物理地址空间,二维虚拟地址空间和实际内存地址是三个不同的概念。操作系统通过段选择子构成二维虚拟地址空间,每个进程有一个4G的地址空间,然后操作系统的内存管理器件把每个进程映射到一维物理地址空间的不同部分,但是因为我们实际机器上大都没有4G内存,所以,实际内存空间是物理地址空间的子集。
分页管理器把地址空间划分成4K大小的页面(非Intel X86体系与之不同),当进程访问某个页面时,操作系统首先在Cache中查找页面,如果该页面不在内存中,则产生一个缺页中断(Page Fault),进程就会被阻塞,直至要访问的页面从外存调入内存中。
我们知道,在处理低优先级的中断时,仍可以发生高优先级的中断。既然缺页过程也是一个中断过程,那么就产生一个问题,即,缺页中断和其他中断的优先级的问题。如果在高于缺页中断的中断优先级上再发生缺页中断,内核就会崩溃。所以在DISPATCH_LEVEL级别以上,绝对不能使用分页内存,一旦使用分页内存,就有发生缺页中断的可能,前面说过,这样会导致内核崩溃。
另一种解释:
虽然可以寻址4GB的内存,而在PC里往往没有如此多的真实物理内存。操作系统和硬件(这里指的是CPU中的内存管理单元MMU)为使用者提供了虚拟内存的概念。Windows的所有程序(包括Ring0层和Ring3层的程序)可以操作的都是虚拟内存。之所以称为虚拟内存,是因为对它的所有操作,最终会变成一系列对真实物理内存的操作。在CPU中有一个重要的寄存器CR0,它是32位的寄存器,其中的一个位(PG位)是负责告诉系统是否分页的。Windows在启动前会将它的PG位置1,即允许分页。宏PAGE_SIZE记录分页大小4KB,4GB的虚拟内存会被分割成1M个分页单元。
有一部分单元会和物理内存对应起来,这种对应不是一一对应,而是多对一的映射,多个虚拟内存页可以映射同一个物理内存页。还有一部分单元会被映射成磁盘上的文件,并标记为脏的(Dirty)。0~0X7FFFFFFF范围内的虚拟内存,即低于2GB的虚拟地址为用户内核模式地址,而0X80000000~0XFFFFFFFF范围内的虚拟内存,即高2GB的虚拟内存,为内核模式地址。Windows的核心代码和Windows的驱动程序加载的位置都是在高2GB的内核地址里,所以一般的应用程序是不能访问到这些核心代码和重要数据的。同时Windows操作系统在进程切换时,保持内核模式地址是完全相同的。也就是说,所有进程的内核地址映射完全一致,进程切换的时候,只改变用户模式地址的映射。
Windows规定有些虚拟内存页面是可以交换到文件中的,这类内存被称为分页内存。而有些虚拟内存永远不会交换到文件中,这些内存被称为非分页内存。当程序的中断请求级在DISPATCH_LEVEL之上(包括DISPATCH_LEVEL层),程序只能使用非分页内存,否则将导致蓝屏死机。
相关拓展:
分页内存和非分页内存
首先介绍几个术语:
进程上下文,就是表示进程信息的一系列东西,包括各种变量、寄存器以及进程的运行的环境。这样,当进程被切换后,下次再切换回来继续执行,能够知道原来的状态。
中断上下文,就是中断发生时,原来的进程执行被打断,那么就要把原来的那些变量保存下来,以便中断完成后再恢复。
Windows NT和Windows 98都是运行在支持虚拟地址空间的计算机上,虚拟地址空间或者映射到一段真实的物理内存,或者映射到交换文件中的页帧。
每一个进程有4G的虚拟地址空间空间(因为一般机器是32位),这4G的空间被分为用户模式地址空间以及用户模式地址空间。无论何时我们需要访问计算机内存,都要使用内核模式的虚拟地址。每一个用户模式进程都有自己的地址上下文,记录了进程信息的一系列东西。当Windows NT调度器把控制从一个进程的当前线程切换到另一个进程的某个线程时,与进程相对应的虚拟地址空间也被更换(执行到别的进程了,也就是跑到另外的一个4G的地址)。线程切换的一个步骤就是改变处理器当前使用的页表,以便它能引用新线程的进程上下文。
虚拟内存系统的特征就是能使软件有一个比物理内存大得多的虚拟内存空间。为了做到这一点,内存管理器需要在物理内存和磁盘文件间交换页帧。但操作系统的某些部分是不能被分页的,这些内存用来支持内存管理器本身。最明显的例子就是,用于处理页故障的代码和数据结构必须常驻内存。
Windows NT把内核模式地址空间分成分页内存池和非分页内存池。(用户模式地址空间总是分页的) 必须驻留的代码和数据放在非分页池;不必常驻的代码和数据放在分页池中。Windows NT为决定代码和数据是否需要驻留非分页池提供了一个简单规则。
非分页内容的空间是很小的,所以一般的东西都会放入分页内存中。
执行在高于或等于DISPATCH_LEVEL级上的代码必须存在于非分页内存中。