我们可以看出 ,按照申请内存大小分类,可以分为两部分

    1.申请小于等于8KB为一个单位的内存,这些内存被用于缓存。(图5中的SinglePage Allocator)

    2.申请大于8KB为一个单位的内存,这些内存称为Multi-Page(或MemToLeave)(图5中的MultiPage Allocator)

 

    对于为什么叫MemToLeave,被称为MemToLeave的原因是由于SQL Server虽然大部分内存被用于缓冲区,但还需要一些连续的内存用于SQL CLR,linked server,backup buffer等操作,32位SQL Server在启动实例时会保留一部分连续的虚拟地址(VAS)用于进行MultiPage Allocator。具体保留多少可以用如下公式计算:

    保留地址=((CPU核数量-4)+256)*0.5MB+256MB,通常在384MB左右。

Memory Clerk

    让我们再来看Memory Clerk,Memory Clerk用于分配内存,用于将Allocate出去的内存进行分类,可以简单的进行如下语句,如图6所示.

    图6.按照Memory Clerk的类别进行分类

    注意:由图4可以看到,Memory Clerk只是分配内存的一部分,另一部分是数据缓存(Buffer Pool)

 Buffer Pool

    在开始讲述Buffer Pool之前,首先想讲一下虚拟内存。

    在Windows中每个进程都有一个虚拟内存(Virtual Address Space  VAS),32位系统是2的32次方,也是4G,这4G被Windows划为两部分,一部分是Windows使用,另一部分才是应用程序使用。虚拟内存并不是实际的物理内存,而是对于物理内存的映射,当物理内存不存在虚拟内存指向的内容时,产生缺页中断,将一部分页面置换出内存,然后将需要的部分从硬盘读到内存,关于这块,可以读我之前写的一篇文章:浅谈操作系统对内存的管理。

    因此Buffer Pool的作用时缓冲数据页,使得未来读取数据时减少对磁盘的访问。

    这个Buffer Pool这部分是图2中设置大小服务器内存所占用的空间。这个小值并不意味着SQL Server启动时能占用这么多内存,而是SQL Server Buffer Pool的使用一旦超过这个值,不会再进行释放了。

    在DBCC MEMORYSTATUS 其中有一部分我们可以看到Buffer Pool的信息,如图7所示。

    图7.Buffer Pool的相关信息

    在SQL Server实例启动时,Buffer Pool所保留的VAS地址空间取决于多个因素:包括实际的物理内存和SQL Server是32位或是64位(这个限制32位是4G,还要划一半给Windows和减去MemToLeave空间),而对于实际上SQL Server所使用的物理内存,可以通过如下语句查看,如图8所示。

    图8.查看Buffer Pool所使用物理内存

    Buffer Pool会按照需要不断的提出内存申请。Buffer Pool如果需要,Buffer Pool会不断消耗内存,直到Windows通知SQL Server内存过低时,Buffer Pool才有可能释放内存,否则Buffer Pool占据了内存不会释放。

    另外值得注意的一点是,Buffer Pool所分配的页面和SQL Server OS页面大小是一致的,也是8192字节,当SQL Server其它部分需要向”Buffer Pool”借内存时,也只能按照8k为单位借,并且这部分内存在物理内存中是不连续的,这听上去像是Buffer Pool内存管理自成体系微笑,可以这么理解,因为Buffer Pool 不使用任何SQL Server的page allocator,而直接使用virtual或AWE SQLOS's的接口。