在观察和分析Windows内存问题时,经常会遇到Page Fault这个概念,其中文翻译为"页错误",它是指当一个进程需要读/写它自己虚拟地址空间(VAS,Virtual Address Space)时,如果此时所要访问的虚拟地址还没有被虚拟内存管理器(VMM,Virtual Memory Manager)影射到物理内存中,那么VMM需要从硬盘上的分页文件中将该页加载到物理内存,这个加载过程就称为 Page Fault。需要注意:从硬盘加载数据到内存是相对而言比较慢的。

       Page Fault又分为:Hard Page Fault和Soft Page Fault。 Hard Page Fault是指所请求的也不再物理内存中,需要从硬盘的分页文件中读取,而Soft Page Fault则是指页面仍然存在与物理内存的standby表中。PerfMon.exe中的内存的Page Faults/sec计数器就是用来观察每秒Page Fault的次数,它 = Hard + Soft Page Fault的和。

       如何来观察Hard Page Fault呢?Page Reads/sec和 Page Input/sec。这两个计数器都是用来观察Hard页从硬盘的读取的,Page Reads/sec代表是因Page Fault从硬盘读取的次数;而Page Input/sec代表的是读取的页面个数。所以,(Page Input/sec) / (Page Read/sec) = 每次Page Fault读取的页面个数。

       那 Pages/sec 呢? = Page Input/sec + Page Output/sec,是因缺页而访问硬盘的读、写页面之和。

 

关于SQL的内存指针

       SQL Server内部的内存消耗大户那就要数Buffer Pool了,所以监控好Buffer Pool可以探测到SQL内存问题。Perfmon.exe专门提供了一些这方面的计数器:

     (1)  MSSQL$<instance>:Memory Manager\Total Server Memory (KB) : Buffer Pool的当前大小;

     (2)  MSSQL$<instance>:Memory Manager\Target Server Memory (KB):Buffer Pool的理想大小。在不存在内存压力的机器上,Total和Target应该是比较接近的。如果Total大大小于Target,那就说明有可能由于内存压力,Buffer Pool大小不能再增长了,需要进一步调查;

     (3)  MSSQL$<instance>:Buffer Manager\Page Life Expectancy:表示SQL Server所期望的加载到Buffer Pool中页面保留的时间(以秒单位)。在内存紧张的情况下,数据页面需要频繁地清空 ,所以微软建议为300秒;但是在内存充足的情况下,它可以很轻松地达到几千秒。

       在我的笔记本上观察了一下这三个计数器,发现Total (= 60.67 MB) 远小于Target (= 1443.8 MB),这是不是说明我的机器存在内存方面的问题,需要加内存啊? 其实不是的,再观察一下第三个计数器,PLE都在24,929秒左右,这说明内存压力不大。我的笔记本配有6G内存,安装的是随Visual Studio 2010一起的SQL Server Express版,并且当前除了偶尔因为学习而偶尔使用SQL Server,基本上对SQL没有什么流量,此时Total远小于Target说明还有很大潜力和挖!


参考资源

Performance Monitor Counters

  1. PerfMon: High Number of Pages/Sec Not Necessarily Low Memory
  2. Monitoring (Database Engine)
  3. Server Memory Options
  4. Effects of min and max server memory