启用selockmemoryprivilege权限后,用virtualalloc配mem_large_pages|mem_commit|mem_reserve和page_readwrite可申请大页内存;必须用virtualfreeex释放,且需检查系统是否支持(getlargepageminimum)。

VirtualAlloc申请大页内存需要先启用SeLockMemoryPrivilege权限
Windows默认禁止普通进程锁定物理内存,而大页(Large Page)本质上是连续的物理内存块,必须通过特权启用。不提前提权会导致VirtualAlloc返回NULL,且GetLastError()返回ERROR_PRIVILEGE_NOT_HELD。
提权需调用AdjustTokenPrivileges,注意:必须以TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY打开进程令牌;特权名是SE_LOCK_MEMORY_NAME(不是字符串字面量,要用宏定义);启用前需先用LookupPrivilegeValue获取LUID。
- 提权操作必须在
VirtualAlloc之前完成,且仅需一次 - 提权失败常见原因是程序未以管理员身份运行(UAC弹窗拒绝或静默失败)
- 即使提权成功,仍需检查
AdjustTokenPrivileges返回值和GetLastError(),它可能“假装成功”但实际未启用(PrivilegesCount == 0)
调用VirtualAlloc时必须指定MEM_LARGE_PAGES和PAGE_READWRITE
大页分配不是可选行为,而是由标志位强制触发:必须同时传入MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES,且保护属性只能是PAGE_READWRITE、PAGE_EXECUTE_READWRITE等允许写入的类型——PAGE_READONLY或PAGE_NOACCESS会直接失败,错误码为ERROR_INVALID_PARAMETER。
另外,大页大小由系统决定(通常是2MB),不能自定义。申请尺寸必须是大页粒度的整数倍,否则VirtualAlloc失败(ERROR_INVALID_PARAMETER);起始地址也必须按大页对齐(但VirtualAlloc会自动处理对齐,无需手动VirtualAlloc(NULL, ...)再调整)。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 最小申请单位就是一页大页(如2MB),哪怕只传1字节也会占用整页
-
MEM_PHYSICAL不能与MEM_LARGE_PAGES共用,后者隐含物理连续性 - 分配后内存内容未初始化(类似
malloc),需自行清零或使用VirtualAlloc配MEM_COMMIT | MEM_RESERVE | MEM_ZEROED(但MEM_ZEROED与MEM_LARGE_PAGES兼容性差,部分Windows版本不支持,建议分配后memset)
大页内存无法用VirtualFree释放,必须用VirtualFreeEx + 当前进程句柄
看起来反直觉,但VirtualFree对大页内存无效——调用后不报错,但内存并未真正释放,下次再申请同大小仍可能失败。正确做法是用VirtualFreeEx,并把当前进程句柄(GetCurrentProcess())作为第一个参数传入。
这是因为大页分配涉及内核级物理页表映射,VirtualFree只处理常规虚拟内存管理路径,而VirtualFreeEx走的是更底层的释放逻辑(即使目标进程是当前进程)。
- 释放前无需
VirtualProtect改权限,直接VirtualFreeEx(hProc, addr, size, MEM_RELEASE) - 释放后务必检查返回值,失败意味着物理页可能卡死(尤其在长时间运行服务中)
- 不要混用:用
VirtualAlloc(带MEM_LARGE_PAGES)分配的,必须用VirtualFreeEx释放;反之亦然
大页内存实际可用性受系统配置和硬件限制
即使代码完全正确,也可能分配失败。常见原因包括:MaxSize注册表项限制(HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\LargePageMinimum)、系统启动时未启用大页支持(某些Hyper-V或安全启动配置会禁用)、CPU不支持(需Intel EPT/AMD RVI,但现代桌面CPU基本都支持)、物理内存碎片(大页要求连续物理页,内存长期运行后易碎片化)。
调试时可查GetSystemInfo返回的dwPageSize(常规页)和dwAllocationGranularity(分配粒度),但大页大小需用GetLargePageMinimum()获取——若返回0,说明系统根本不支持大页(如Windows Home版默认关闭,或组策略禁用)。
- 开发阶段务必用
GetLargePageMinimum()兜底判断,避免硬编码2MB - 分配失败时,应降级到普通
VirtualAlloc(去掉MEM_LARGE_PAGES),而不是抛异常或退出 - 大页适合长期驻留、访问密集的场景(如数据库缓冲池、实时音视频处理),不适合短生命周期对象——它的代价是全局物理内存压力和更难回收
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










