缓存和内存管理器性能问题疑难解答

在 Windows Server 2012 之前,两个主要的潜在问题导致系统文件不断缓存增长,直到在某些工作负载下可用内存几乎耗尽。 当这种情况导致系统运行缓慢时,可以确定服务器是否面临这些问题之一。

要监视的计数器

  • “内存\长期平均待机缓存生存期”小于 1800 秒

  • 内存\可用(以字节、千字节或兆字节为单位)

  • 内存\系统缓存驻留字节数

如果“内存\可用兆字节数”不足,同时“内存\系统缓存驻留字节数”占用物理内存的很大一部分,则可以使用 RAMMAP 找出缓存的用途。

系统文件缓存包含 NTFS 元文件数据结构

此问题是由 RAMMAP 输出中大量活动元文件页所指示的,如下图所示。 在访问数百万个文件的繁忙服务器上可能会出现此问题,从而导致缓存的 NTFS 元文件数据无法从缓存中释放。

rammap view

DynCache 工具曾经缓解过这个问题。 在 Windows Server 2012+ 中,体系结构已经过重新设计,此问题不应再存在。

系统文件缓存包含内存映射文件

RAMMAP 输出中出现大量活动映射文件页便表明存在此问题。 这通常表示服务器上的某个应用程序正在使用设置了 FILE_FLAG_RANDOM_ACCESS 标志的 CreateFile API 来打开多个大型文件。

知识库文章 2549369 中详细介绍了此问题。 FILE_FLAG_RANDOM_ACCESS 标志表明缓存管理器尽可能长时间地将文件的映射视图保留在内存中(直到内存管理器没有发出内存不足的信号)。 同时,此标志会命令缓存管理器禁用文件数据的预提取。

Windows Server 2012+ 中的工作集调整改进在一定程度上缓解了这种情况,但要从根本上解决此问题,则要求应用程序供应商不能使用 FILE_FLAG_RANDOM_ACCESS。 应用供应商的替代解决方案可能是在访问文件时使用低内存优先级。 这可以使用 SetThreadInformation API 来实现。 以低内存优先级访问的页面会更激进地从工作集中删除。

从 Windows Server 2016 开始,缓存管理器通过在做出修剪决定时忽略 FILE_FLAG_RANDOM_ACCESS 来进一步缓解这一问题,因此它就像任何其他没有 FILE_FLAG_RANDOM_ACCESS 标志的文件一样被打开(缓存管理器仍然使用此标志来禁用文件数据的预取)。 如果你使用此标志打开了大量文件,并且以真正随机的方式进行访问,则仍然会导致系统缓存膨胀。 强烈建议应用程序不要使用 FILE_FLAG_RANDOM_ACCESS

始终超过远程文件脏页阈值

如果系统在从远程客户端写入期间偶尔出现速度减慢,则表明出现了此问题。 如果大量数据从快速远程客户端写入慢速服务器目标,可能出现了此问题。

在 Windows Server 2016 之前,在这种情况下,如果达到缓存中的脏页阈值,则进一步的写入将表现为写直达。 这可能会导致大量数据刷新到磁盘,如果存储速度较慢,可能会导致延迟时间边长,从而导致远程连接超时。

在 Window Server 2016 和更高版本中,已实施缓解措施,以减少超时的可能性。 为远程写入实现了单独的脏页阈值,超过阈值时将执行内联刷新。 这可能会导致在大量写入活动期间偶尔减速,但在大多数情况下可以消除超时的风险。 默认情况下,此远程脏页阈值为每个文件 5 GB。 对于某些配置和工作负载,更改数字可以优化性能。

如果默认大小 5 GB 不适合配置,建议尝试以 256 MB 为增量增加限制,直到性能令人满意为止。 请注意以下事项:

  • 需要重新启动才能使对此注册表项的更改生效。

  • RemoteFileDirTypageThreshold 的单位是页数(页面大小由缓存管理器管理)。 这意味着应将其设置为所需的大小(以字节为单位,除以 4096)。

  • 建议的值为 128 MB <= N <= 可用内存的 50%。

  • 通过将其设置为 -1,可以完全禁用此阈值。 不建议这样做,因为这会导致远程连接超时。

例如,如果要将限制设置为 10GiB,即 10,737,418,240 字节/4096 = 2,621,440,即十进制 DWORD 值2621440。

可以使用以下注册表值控制此阈值。

  • 键:HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management
    • 类型:DWORD
    • 值名称RemoteFileDirtyPageThreshold
    • 值数据:十进制 - 页面数(缓存管理器管理的页面大小)。