启用“锁定内存页”策略可防止SQL Server内存被换出到虚拟内存,需管理员通过gpedit.msc授予服务账户SeLockMemoryPrivilege权限,并由进程调用VirtualLock锁定页对齐内存,推荐使用服务SID以保障权限持久性。
windows 系统服务要稳定驻留物理内存、避免被换出到页面文件,核心在于“锁定页”(lock pages in memory, lpim)机制——它不是应用层简单调用 api 就能生效的功能,而是依赖操作系统权限、进程配置与内核级协同的一整套技术路径。
系统级权限是前提:启用“锁定内存页”策略
普通用户或服务账户默认无权锁定内存。必须由管理员通过组策略授予“锁定内存页”(SeLockMemoryPrivilege)权限:
- 运行 gpedit.msc → 计算机配置 → Windows 设置 → 安全设置 → 本地策略 → 用户权利指派 → 双击“锁定内存页”
- 添加目标服务账户(推荐使用服务 SID,如 NT SERVICE\MSSQLSERVER),而非具体用户名,避免账户变更后失效
- 修改后需重启服务或整个系统(取决于服务类型),权限才真正加载进令牌
服务进程需主动调用 VirtualLock 并满足约束条件
获得权限只是第一步。服务进程自身必须在运行时显式调用 VirtualLock 锁定关键内存区域,且须注意以下限制:
- 内存必须以页对齐方式分配(如用 VirtualAlloc 分配,大小为 4KB 的整数倍)
- 单次锁定总量受进程工作集上限影响;可先调用 SetProcessWorkingSetSize 扩大配额(例如设为 1GB 最小/最大值)
- 锁定失败时检查 GetLastError():常见错误码包括 ERROR_PRIVILEGE_NOT_HELD(权限未生效)、ERROR_WORKING_SET_QUOTA(配额不足)、ERROR_NOT_ENOUGH_MEMORY(物理内存紧张)
驱动与内核组件的内存锁定更底层
系统服务若依赖驱动(如存储、网络、GPU 驱动),其内存锁定行为不经过用户态 API,而是由内核调用 MmLockPagableCodeAddress 或 MmProbeAndLockPages 实现:
- 这类锁定通常用于 DMA 缓冲区、中断上下文数据结构等不可分页区域
- 占用内存会归类为 Driver Locked,在 RamMap 工具中可见,但任务管理器不显示
- 若发现系统启动后大量内存被 Driver Locked 占用,应排查第三方驱动(如 PCIe 设备驱动、安全软件驱动)是否过度锁定
SQL Server 等典型服务的实践参考
SQL Server 是最常启用 LPIM 的服务,其配置逻辑具有代表性:
- SQL Server 启动时检测服务账户是否拥有 SeLockMemoryPrivilege 权限
- 若检测成功,自动调用 VirtualLock 锁定 Buffer Pool 中的大部分页(除极少数元数据外)
- 此时即使系统内存压力升高,SQL Server 的缓冲池也不会被换出,从而保障查询响应稳定性
- 注意:LPIM 在 AWE 模式下(32位旧版)已弃用;64位环境下直接依赖 VirtualLock + 组策略组合

















