服务器从 16G 升级到 32G 后,为 SQL Server 分配 24G 内存,预留 8G 给操作系统。但出现典型问题:SQL Server 启动后无任何访问,依然快速占满 24G 内存,导致服务器卡顿、无响应。执行 DBCC FREEPROCCACHE 清理缓存无效。本文基于真实生产环境排查,从内存机制、分版本查询、配置优化、急救方案四个维度完整解决问题,适用于 SQL Server 2014 / 2016+ 等主流版本。
一、问题现象
- 服务器内存:32GB
- SQL Server 最大内存:24GB(24576MB)
- 现象:
- 无业务访问,内存依然快速占满
- 服务器卡顿、I/O 飙升、远程桌面卡顿
- 清理执行计划缓存无效
- 无慢查询、无大事务、无异常会话
二、根本原因(最重要)
通过内存分配器查询发现:内存几乎全部被 MEMORYCLERK_SQLBUFFERPOOL 占用。
这是 SQL Server 的正常设计机制,不是 Bug:
- Buffer Pool 会尽可能占用 max server memory 以内的所有内存用于缓存数据
- 无访问时也不会主动释放
- 小内存服务器(8G/16G/32G)最容易出现 “占满即卡”
真正导致卡死的原因:系统预留内存不足 + SQL Server 内存释放不及时。
三、不同版本 SQL Server 内存查询脚本(2014 / 2016+)
由于 2014 与 2016+ 字段不兼容,提供两套可直接运行脚本。
3.1 SQL Server 2016+ 查询会话内存
SELECT TOP 20
session_id AS SPID,
(used_memory_kb / 1024) AS 占用内存MB,
login_name, host_name, program_name
FROM sys.dm_exec_sessions
ORDER BY used_memory_kb DESC;
3.2 SQL Server 2014 查询内存(本文实战环境)
SELECT TOP 20
session_id AS SPID,
(memory_usage * 8) / 1024 AS 占用内存MB
FROM sys.dm_exec_sessions
WHERE session_id > 50
ORDER BY memory_usage DESC;
3.3 通用内存分配器查询(所有版本通用,定位内存黑洞)
SELECT TOP 10
type AS 内存分配器,
pages_kb / 1024 AS 占用MB
FROM sys.dm_os_memory_clerks
ORDER BY pages_kb DESC;
执行后你会发现:BUFFERPOOL 占用 90%+ 内存。
四、32G 服务器最优内存配置(永久解决)
4.1 设置最大内存(必须)
sp_configure 'show advanced options',1
RECONFIGURE
sp_configure 'max server memory (MB)',24576
RECONFIGURE
4.2 优化内存释放(防止系统卡死)
sp_configure 'min server memory (MB)',0
RECONFIGURE
sp_configure 'optimize for ad hoc workloads',1
RECONFIGURE
作用:
- 让 SQL Server 能主动释放内存
- 避免执行计划缓存无限膨胀
4.3 服务器已卡顿时急救脚本
DBCC FREEPROCCACHE
DBCC DROPCLEANBUFFERS
注意:仅临时缓解,不能根治。
五、为什么清缓存没用?
- DBCC FREEPROCCACHE 只清执行计划
- 真正占内存的是 BUFFERPOOL(数据缓存)
- 清理数据缓存才能降内存,但会影响性能
六、3 步标准排查流程
七、不同内存服务器推荐配置
表格
| 8G | 4096 | 4G |
| 16G | 10240 | 6G |
| 32G | 24576 | 8G |
| 64G | 51200 | 14G |
八、总结
- 限制最大内存
- 开启即席工作负载优化
- 保证系统预留足够内存
按照本文配置后,内存可稳定运行,不再出现无访问占满卡死问题。
版权声明
本文基于真实生产环境实战总结,更详细的排查过程与脚本说明可参考本人博客:https://www.lnmpweb.cn/archives/7462



