当前位置: 首页 > news >正文

使 32 位程序使用大于 2GB 的内存

不管在 32 位 Windows 上还是在 64 位 Windows 上,32 位的应用程序都只能使用最大 2GB 的内存,这是我们司空见惯的一个设定。但其实 Windows 提供了一些方法让我们打破这样的设定,使程序使用大于 2GB 的内存。


阅读本文,你将了解:
1. 为什么 32 位程序只能使用最大 2GB 内存;
1. 让 32 位程序使用大于 2GB 内存的两种方法;
1. 声明支持大于 2GB 内存后,能使用多少内存。

为什么 32 位程序只能使用最大 2GB 内存?

32 位寻址空间只有 4GB 大小,于是 32 位应用程序进程最大只能用到 4GB 的内存。然而,除了应用程序本身要用内存,操作系统内核也需要使用。应用程序使用的内存空间分为用户空间和内核空间,每个 32 位程序的用户空间可独享前 2GB 空间(指针值为正数),而内核空间为所有进程共享 2GB 空间(指针值为负数)。所以,32 位应用程序实际能够访问的内存地址空间最多只有 2GB。

让 32 位程序使用大于 2GB 内存的两种方法

editbin

这是 Visual Studio 2017 采用的做法。我们需要使用到两个工具——editbindumpbin。前者用于编辑我们编译生成好的程序使之头信息中声明支持大于 2GB 内存,后者用于查看程序的头信息验证我们是否改好了。

编辑一个程序使之声明支持大于 2GB 内存的命令是:

editbin /largeaddressaware xxx.exe

其中,xxx.exe 是我们准备修改的程序,可以使用相对路径或绝对路径(如果路径中出现空格记得带引号)。

验证这个程序是否改好了的命令是:

dumpbin /headers xxx.exe | more

同样,xxx.exe 是我们刚刚改好准备检查的程序,可以使用相对路径或绝对路径。

editbin 改之前和改之后用 dumpbin 查看我们的程序头信息,得到下面两张图:

改之前
改之后

注意到 FILE HEADER VALUES 块的倒数第二行多出了 Application can handle large (>2GB) addresses

如果没发现,一定是你命令执行中发生了错误,检查一下吧!最容易出现的错误是执行后发现根本就没有这个命令。是的,editbin 命令从哪里来呢?可以在开始菜单中的 Visual Studio 文件夹中查找 Developer Command Prompt for VS 2017,运行这个启动的命令行中就带有 editbin 和 dumpbin。

![本机工具提示符]({{ site.baseurl }}/assets/2017-09-12-where-to-find-editbin.png)

如果希望能够在 Visual Studio 编译的时候自动调用这个工具,请参见:LargeAddressAware Visual Studio 2015 C#。

编译成 AnyCPU (Prefer 32-bit)

这是本文更推荐的做法,也是最简单的做法。方法是打开入口程序集的属性页,将“目标平台”选为“AnyCPU”,然后勾选“首选 32 位”。需要注意的是,这种生成方式是 .Net Framework 4.5 及以上版本才提供的。

![AnyCPU (Prefer 32-bit)]({{ site.baseurl }}/assets/2017-09-12-anycpu-with-32bit-preferred-build.png)

至于 AnyCPU (Prefer 32-bit) 和 x86 两种生成方式的区别,请参见:What is the purpose of the “Prefer 32-bit” setting in Visual Studio 2012 and how does it actually work?。

声明支持大于 2GB 内存后,能使用多少内存?

对于 32 位操作系统,程序依然只能使用 2GB 内存,除非开启了 /3GB 开关,开启方法详见:/3GB。开启后,应用程序的用户态将可以使用 3GB 内存,但内核态将只能使用 1GB 内存。微软认为,是否打开 /3GB 开关是计算机设备开发商需要做的事情,开发商也需要自己测试开启后驱动程序的性能表现和稳定性。

对于 64 位操作系统,Windows 将很豪放地将 4GB 全部贡献给这样的程序,因为系统自己已经有更多的内存寻址空间可以使用了,没必要跟 32 位应用程序抢占寻址空间。

参考资料

  • AnyCPU (32bit preferred)
    • What is the purpose of the “Prefer 32-bit” setting in Visual Studio 2012 and how does it actually work?
  • IMAGE_FILE_LARGE_ADDRESS_AWARE
    • Memory Limits for Windows and Windows Server Releases
    • Getting 32-bit application to use more than 2GB on 64-bit Windows 7?
    • /LARGEADDRESSAWARE (Handle Large Addresses)
    • Why 2 GB memory limit when running in 64 bit Windows?
    • Pushing the Limits of Windows: Paged and Nonpaged Pool
    • Can a 32bit process access more memory on a 64bit windows OS?
  • /3GB
    • /3GB
  • editbin/dumpbin
    • editbin /largeaddressaware xxx.exe
    • dumpbin /headers xxx.exe | more
    • verify if largeAddressAware is in effect?
    • LargeAddressAware Visual Studio 2015 C#

相关文章:

  • 如何向整个 Git 仓库补提交一个文件
  • .Net Framework 4.x 程序到底运行在哪个 CLR 版本之上
  • 优化 UWP 中图片的内存占用
  • UWP 中的 LaunchUriAsync,使用默认浏览器或其他应用打开链接
  • WPF/UWP 绑定中的 UpdateSourceTrigger
  • 深入了解 WPF Dispatcher 的工作原理(Invoke/InvokeAsync 部分)
  • 深入了解 WPF Dispatcher 的工作原理(PushFrame 部分)
  • DependencyProperty.UnsetValue 的正确打开方式
  • 如何组织一个同时面向 UWP/WPF/.Net Core 控制台的 C# 项目解决方案
  • 出让执行权:Task.Yield, Dispathcer.Yield
  • 如何防止后台线程抛出的异常让程序崩溃退出
  • CaptureMouse/CaptureStylus 可能会失败
  • 使用 ExceptionDispatchInfo 捕捉并重新抛出异常
  • 使用 Task.Wait()?立刻死锁(deadlock)
  • 如何实现一个可以用 await 异步等待的 Awaiter
  • [case10]使用RSQL实现端到端的动态查询
  • ComponentOne 2017 V2版本正式发布
  • CoolViewPager:即刻刷新,自定义边缘效果颜色,双向自动循环,内置垂直切换效果,想要的都在这里...
  • download使用浅析
  • EventListener原理
  • express.js的介绍及使用
  • Java 11 发布计划来了,已确定 3个 新特性!!
  • JavaSE小实践1:Java爬取斗图网站的所有表情包
  • java概述
  • JS基础之数据类型、对象、原型、原型链、继承
  • Netty 4.1 源代码学习:线程模型
  • rabbitmq延迟消息示例
  • ⭐ Unity 开发bug —— 打包后shader失效或者bug (我这里用Shader做两张图片的合并发现了问题)
  • vue-router 实现分析
  • 飞驰在Mesos的涡轮引擎上
  • 极限编程 (Extreme Programming) - 发布计划 (Release Planning)
  • 聊聊springcloud的EurekaClientAutoConfiguration
  • 前嗅ForeSpider教程:创建模板
  • 使用putty远程连接linux
  • 视频flv转mp4最快的几种方法(就是不用格式工厂)
  • 一些基于React、Vue、Node.js、MongoDB技术栈的实践项目
  • MyCAT水平分库
  • ​软考-高级-系统架构设计师教程(清华第2版)【第1章-绪论-思维导图】​
  • #1015 : KMP算法
  • (173)FPGA约束:单周期时序分析或默认时序分析
  • (2)nginx 安装、启停
  • (4)Elastix图像配准:3D图像
  • (4)logging(日志模块)
  • (70min)字节暑假实习二面(已挂)
  • (9)目标检测_SSD的原理
  • (附源码)ssm教材管理系统 毕业设计 011229
  • (三维重建学习)已有位姿放入colmap和3D Gaussian Splatting训练
  • (一)为什么要选择C++
  • (转)Groupon前传:从10个月的失败作品修改,1个月找到成功
  • (转)winform之ListView
  • **PHP二维数组遍历时同时赋值
  • *2 echo、printf、mkdir命令的应用
  • .NET 5.0正式发布,有什么功能特性(翻译)
  • .NET CF命令行调试器MDbg入门(一)
  • .NET Core 2.1路线图