背景:我有一个 SQL Server 实例在我们的一台虚拟机上运行,内存为 64 GB。目前最大限制为 60 GB,最小限制为 0 GB。SQL Server 是服务器上运行的唯一一个消耗大量内存的应用程序。
我最近推出了一项功能,该功能会向 SQL Server 发出重复的昂贵查询,每当有大量用户使用该功能时,内存使用量就会按预期增加。我还没有达到极限,但我很好奇当我们接近极限时会发生什么。
根据 MS 文档,我了解到 SQL Server 会根据需要动态处理内存以供使用,但我无法找到有关 SQL Server 动态释放内存的逻辑的任何信息。
问题:
- 它是否在达到指定限制之前就开始释放内存?还有什么触发内存释放?
- SQL Server 如何确定要释放哪些内存?它是否以 FIFO 方式释放内存?
我是否完全忽略了某些要点?
这主要是因为内部内存使用情况是一个实现细节,在主要版本甚至 CU 之间可能会(并且确实会)发生变化。更不用说可以进一步改变行为的跟踪标志的数量了。
您已经找到了两个旋钮
MinServerMemory
,MaxServerMemory
它们构成了管理员可以用来影响操作系统环境 (OSE) 中整体行为的基础。除此之外,还有一些跟踪标志,其中大多数都不公开,可以改变行为。下一个项目是管理员控制的,即内存量和在 OSE 上运行的其他应用程序。SQL Server 会监听 Windows,它可以为 OSE 设置低内存条件,以告知应用程序计算机内存不足,并且应用程序可以这样做(如果它们订阅了该事件)。SQL Server 通过在内部设置不同的标志来采取行动,然后导致各种职员实施外部内存压力例程 - 并非所有人都会这样做。如果他们实施了这项措施,它就会启动,至于是否有帮助,谁也说不准。如果您已经将最大服务器内存设置得很高,让您的防病毒软件或任何软件启动并扫描系统上的所有内容,同时占用 20 GB 的内存可能不是个好主意。
最后,还有内部内存压力,即 SQL Server 内部不同内存使用量之间的压力。有些项目会实现内部内存压力例程,有些则不会,例如锁管理器不会放弃内存。
最后一个应用程序级可控项目(再次,有点)是工作负载。如果没有经过调整的查询并占用大量并发锁,锁管理器将增大规模并且永远不会归还。应用程序调整(以及查询调整)可以并且将使您能够尽可能多地允许大内存授予(取决于版本和 CU)超过最大服务器内存,这可能会导致不良的事件链反应。
如果您想了解有关 SQL Server 内部和外部内存管理的更多信息,我推荐《 SQL Server Internals 》一书。它是 2012 年出版的,但其核心部分仍然适用。