不管在 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 采用的做法。我们需要使用到两个工具——editbin 和 dumpbin。前者用于编辑我们编译生成好的程序使之头信息中声明支持大于 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 位应用程序抢占寻址空间。

参考资料

使 32 位程序使用大于 2GB 的内存的更多相关文章

  1. win764位系统上让32位程序能申请到4GB内存方法

    win764位系统上让32位程序能申请到4GB内存方法. 2016年09月18日 18:36:26 阅读数:1550 最近测试一个32位程序总是在1.2G左右内存时崩溃,怀疑是内存申请失败,本身32位 ...

  2. 如何使32位Win7支持超过4GB的内存,而不装64位

    如何使32位Win7支持超过4GB的内存 让32位系统支持更大的内存超过4G [情况参数:] PC: 联想商用台式机,M4350 RAM: 1600, DDR3 , 2GB OS: Win7 专业版 ...

  3. 64位系统上运行32位程序能否申请到8G内存?

    申请不到,因为64为系统在运行32位程序的时候只是为了向下兼容而已,对于32位程序来讲,申请8G的存储空间没有任何意义,因为32位的程序最大寻址空间只有4G,32位程序在编译之后的机器代码也只有32位 ...

  4. 记32位程序(使用3gb用户虚拟内存)使用D3DX9导致的一个崩溃的问题

    为了增加32位程序的用户虚拟内存的使用量,我们使用了/LARGEADDRESSAWARE编译选项来使32位程序可能使用到3gb的内存,能否使用到3gb内存也跟平台.系统和设置有关系,现摘抄部分作为参考 ...

  5. 转:如何在32位程序中突破地址空间4G的限制

    //如何在32位程序中突破地址空间4G的限制 //首先要获得内存中锁定页的权限 #define _WIN32_WINNT 0x0501 //xp系统 #include <windows.h> ...

  6. C# 32位程序访问64位系统注册表

    原文:C# 32位程序访问64位系统注册表 我的上一篇文章已经阐述了“32位程序和64位程序在64位平台上读\写注册表的区别”,那么接下来将要回答上篇所留下来的一个问题:32位程序如何访问64位系统注 ...

  7. 通过修改EIP寄存器实现32位程序的DLL注入

    功能:通过修改EIP寄存器实现32位程序的DLL注入 <如果是64位 记得自己对应修改汇编代码部分> 原理:挂起目标进程,停止目标进程EIP的变换,在目标进程开启空间,然后把相关的指令机器 ...

  8. 64位Ubuntu运行32位程序时报文件不存在(No such file or Directory)的一种解决办法

    尝试在64位Ubuntu下面运行32位程序时, 一直说 文件不存在(No such file or directory), 我只想说++. 你tm说个文件格式不正确不就好了? 非得说个文件不存在! 真 ...

  9. Ubuntu14.04 64位运行32位程序

    最近公司新增的机器安装Ubuntu14.04 64bit导致之前在32bit下编译的Qt工具软件无法运行. 于是google的了一下找到一些解决办法,但不能保证全部32bit的Qt程序都能正常,测试了 ...

随机推荐

  1. gulp+es6构建页面

    遇到的问题: 1.es6如何使用,定义一个demo.js //demo.js export default class demo { // 构造函数 constructor(){ //在构造函数中调用 ...

  2. Session存储

    session其实分为服务器端Session和客户端Session. 当用户首次与Web服务器建立连接的时候,服务器会给用户分发一个sessionid作为标识.用户每次提交页面,浏览器都会把这个ses ...

  3. winform如何让窗体不显示Icon但在任务栏中显示Icon

    protected override void OnShown(EventArgs e) { base.OnShown(e); const int WM_SETICON = 0x80; Bitmap ...

  4. Linux下部署 jar包

    1.windows和linux执行jar命令是一样的,java -jar xxx.jar 2.使用nohup命令将jar程序设置成后台运行,运行日志输出到nohup.out,关闭窗口无影响 nohup ...

  5. web前端 —— 移动端知识的一些总结

    个人在移动端的一些总结归纳,有新的知识点会一直更新 一.css部分 1.meta标签 <meta name="viewport" content="width=de ...

  6. 详解offset

    offset offset 译为“偏移量”,是javascript很重要的一个概念.涉及到便宜量的主要有offsetLeft.offsetTop.offHeight.offsetWidth这四个属性还 ...

  7. css布局(转载)

    单列布局 水平居中 水平居中的页面布局中最为常见的一种布局形式,多出现于标题,以及内容区域的组织形式,下面介绍四种实现水平居中的方法(注:下面各个实例中实现的是child元素的对齐操作,child元素 ...

  8. 34-THREE.JS 游泳圈

    <!DOCTYPE html> <html> <head> <title>Example 05.08 - Basic 3D geometries - T ...

  9. Linux下安装Nginx教程

    什么是Nginx? Nginx ("engine x") 是一个高性能的 HTTP 和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服务器,在高连接并发的情况下N ...

  10. 013——数组(十三) array_push array_rand array_reverse

    <?php /* 数组 array_push array_rand array_reverse */ //array_push()在数组的末端,增加一个或多个元素,入栈 /*$array = a ...