摘自 SQL Server 2008 R2 联机丛书:
服务器内存选项
当 SQL Server 动态使用内存时,它会定期查询系统以确定可用的物理内存量。SQL Server 使用内存通知 API
QueryMemoryResourceNotification
确定缓冲池何时可以分配内存和释放内存。
摘自 SQL Server 2005/2008 联机丛书:
服务器内存选项
当 SQL Server 动态使用内存时,它会定期查询系统以确定可用物理内存的数量。在 Microsoft Windows 2000 下,SQL Server 会根据服务器活动增加或缩小缓冲区缓存,以将可用物理内存保持在 4 MB 到 10 MB 之间。维护此可用内存可防止 Windows 2000 分页。如果可用内存较少,SQL Server 会将内存释放给 Windows 2000。
在 Windows Server 2003 下,SQL Server 使用内存通知 API
QueryMemoryResourceNotification
确定缓冲池何时可以分配内存和释放内存。
我知道 SQL Server 会管理自己的内存使用情况。如果服务器的可用内存不足,SQL Server 会释放一些内存(使自己挨饿)。这是默认、理想、首选的行为。但我见过很多 SQL Server 在以下情况下不释放内存的情况:是其他饥饿应用程序(即遭受大量分页错误)。
然后我发现提到它可以采取天SQL Server 实际释放内存:
专业 Microsoft SQL Server 2008 管理、内存使用
SQL Server 是性能最好的服务器应用程序之一。当操作系统触发低内存通知事件时,SQL 将释放内存供其他应用程序使用,如果计算机上正在运行另一个占用大量内存的应用程序,则实际上会耗尽内存。好消息是,SQL 每次只会释放少量内存,因此可能需要数小时,甚至几天,然后 SQL 才会开始受到影响。不幸的是,如果其他应用程序迫切需要更多内存,则 SQL 可能需要数小时才能释放足够的内存,以便其他应用程序在不进行过多分页的情况下运行。
这听起来对吗?SQL Server 是一个运行良好的服务器应用程序,它将使服务器瘫痪天?
是否有一个选项(除了设置 SQL Server 内存使用上限之外)可以加快 SQL 释放内存的速度?
答案1
首先了解 Windows 内存的工作原理(参见如何判断我的 Windows 服务器是否正在交换?)。
现在我们知道分页并不全是坏事,SQL Server 释放内存的速度不够快,无法让 Windows 上具有大量内存峰值的其他应用程序在我们认为合理的时间内得到满足。
这不会花“几天”,而是需要几天的时间SQL遭受损失的不是其他应用程序。而是其他应用程序需要花费数小时才能在内存中获得足够的可用页面,以便以可接受的速率运行(假设请求大量内存页面)。
一般来说,如果其他应用程序必须存在于具有 SQL Server 的计算机上,则最佳做法是设置 SQL 的内存限制(如果已知其他应用程序的内存需求有所变化)。
我很喜欢关于 SQL Server 的引言“行为良好”。事实上,它表现得很好;只是需要很长时间(相对而言)。
答案2
SQL Server 使用两种类型的内存可以释放:
- 数据页(缓冲池)
- 缓存
只要发出内存不足的情况信号,两者都会积极地进行调整。
这缓存描述于问与答:钟表指针 - 它们是用来做什么的?
这缓冲池机制描述于缓冲区管理
- 只要缓存未在使用中,就可以被修剪。
- 缓冲池干净页可以立即修剪(脏页需要先刷新到磁盘)
总而言之,SQL Server 可以在几秒钟内释放所有可以立即释放的内存(干净的页面、未固定的缓存)。刷新 IO 完成后,脏页就可以释放。我不知道“需要几天时间”的想法是从哪里来的……