从SQL Server回收内存


10

我有一个SQL Server实例,该实例的内存使用量逐渐增加,直到Windows不再提供它为止。偶尔的大查询结果会导致实例增长,这似乎是合乎逻辑的。

有什么方法可以说服SQL Server释放不再需要的内存(除了重新启动服务)?

编辑:
我正在使用SQL Server 2000 SQL Server 8.00.2039-SP4(标准版)

我可以使用以下查询找到答案:

SELECT 'SQL Server ' 
    + CAST(SERVERPROPERTY('productversion') AS VARCHAR) + ' - ' 
    + CAST(SERVERPROPERTY('productlevel') AS VARCHAR) + ' (' 
    + CAST(SERVERPROPERTY('edition') AS VARCHAR) + ')'

Answers:


19

这正是SQL Server 应该工作的方式。

如果该计算机上有其他服务,并且不希望SQL使用所有可用内存,则需要设置最大服务器内存。请参阅MSDN上的SQL Server内存选项


1
听起来更像是一个错误而不是一个功能……它发生在我身上。SQL Server占用95%的可用RAM来执行某项操作,并在完成后无法释放它。
炼金术

1
@Alchemical取决于您所说的“ 完成 ”。SQL Server 可以利用计算机中的所有RAM。使用它作为磁盘缓存。在完成使用SQL Server之前,它不会“ 完成 ”使用它作为磁盘缓存。
伊恩·博伊德

8

其他海报是正确的,这是设计使然,但是您绝对希望将最大内存限制为比服务器的RAM小一点。考虑以下事件序列:

  • SQL 2000愉快地运行,消耗了服务器的所有RAM
  • 有人进入RDP,或者您必须拉起IE才能下载补丁,或者开始备份,无论如何
  • SQL必须重新分配并释放足够的内存才能使操作系统正常工作
  • 释放内存和分页到磁盘时,性能下降
  • 一旦稳定就一切顺利
  • 其他操作完成,SQL逐渐回收释放的RAM
  • 重复

为避免这种情况,请将最大服务器内存限制配置为实际物理内存的大约80-90%。有关SQL 2000的说明,请访问:http : //msdn.microsoft.com/zh-cn/library/ms178067.aspx


请记住,此行为是2005和2008-2000不会按需向OS释放内存。
Paul Randal

2
并非完全按需,但确实会将内存释放回操作系统。从我发布的链接中:“当SQL Server动态使用内存时,它会定期查询系统以确定可用的物理内存量。在Microsoft Windows 2000下,SQL Server会增加或缩小缓冲区缓存以将可用的物理内存保持在4 MB之间和10 MB(取决于服务器活动)。维护此可用内存可防止Windows 2000进行分页。如果可用内存较少,则SQL Server会将内存释放到Windows2000。如果有更多可用内存,则SQL Server会将内存分配给缓冲池。”
sh-beta 2009年

啊-不错-它确实可以减少一点物理内存的技巧-对!
Paul Randal

4

仅当操作系统发出信号表明内存不足或停止并重新启动服务时,它才会释放它。要做的是通过配置“最大服务器内存”值来限制SQ​​L使用的最大数量。如果服务器上没有其他需要RAM的东西了(希望那里没有),我也不必担心。


4

因此,总结一下答案:

没有任何方法可以提示MS SQL Server释放不需要的内存。SQL Server应该在需要时自动释放内存,但在此之前不应该释放内存。并且,如果您遇到内存问题,则应减小“最大服务器内存”内存选择的值。


3

SQL Server将消耗内存,并且不会将其交还给内存,除非操作系统告知内存有压力。正如波特曼指出的那样,这是设计使然,如果要限制内存消耗,则需要设置SQL Server将使用的最大服务器内存。


2

请记住,您所描述的行为都是从SQL Server 2005开始的,当内存管理器被重写(除其他外)以响应来自操作系统的内存压力请求。

对于SQL Server 2000及更早版本,一旦操作系统抢了内存,它就不会将其归还。

CodeSlave-您运行的是2000、2005还是2008?


啊哈...确实是2000年的SQL
BIBD

3
当操作系统为它喊叫时,它不会将其退还给您,但是如果发现操作系统的可用物理内存低于某个阈值,它会将其退还给您。参见msdn.microsoft.com/en-us/library/ms178067.aspx
sh-beta(2009年

为了强化sh-beta所说的,SQL Server 2000仅在注意到操作系统的物理内存不足时才释放内存,因为直到Windows XP(2001)Windows才添加API来允许“ 操作系统大喊大叫”。它msdn.microsoft.com/en-us/library/aa366799(v=vs.85).aspx)。SQL Server 2005利用Windows的这一新功能。但是,在编写SQL Server 2000时,操作系统无法为其喊叫,这迫使SQL Server定期检查内存压力。
伊恩·博伊德

0

我知道这是一个老问题,但是强制(至少是更新的)SQL释放内存的一种方法是编写一个应用程序,该应用程序以块为单位分配尽可能多的内存,等待(例如)15秒(例如Sleep(15000))释放分配的内存并退出;我尝试了这一点,SQL确实释放了内存,因此系统恢复了它的RAM。使用C / C ++编写像上面的代码几乎是微不足道的,只需要设置一堆链结来容纳内存块链(指针和大小),然后在“ malloc()”失败时逐渐减小大小,直到达到最小(例如小于1024),然后遍历链接列表以释放分配的块

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.