不管在 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 位应用程序抢占寻址空间。

参考资料

使 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. linux环境变量 export命令详解

    由host $ export DVSDK="${HOME}/ti-dvsdk_dm368-evm_xx_xx_xx_xx"引发的问题 1.${HOME}:首先, HOME 是个变量 ...

  2. replace()函数用法

    replace()函数表示将用一个字符串替换字符串中的所出现的特定内容. 语法为:replace(字段1,字段2,字段3),意思为字段3将会替换字段1里与字段2相同的内容  列如: table1 st ...

  3. Kafka消息topic分区

      kafka是为分布式环境设计的,因此如果日志文件,其实也可以理解成消息数据库,放在同一个地方,那么必然会带来可用性的下降,一挂全挂,如果全量拷贝到所有的机器上,那么数据又存在过多的冗余,而且由于每 ...

  4. 热备模式相关问题2.txt

    --//上午测试热备模式相关问题,就是如果打开热备模式,如果中间的归档丢失,oracle在alter database end backup ;时并没有应用日志. --//虽然热备份模式文件头scn被 ...

  5. sqlserver存储过程杀掉数据库中死锁

    Create proc p_lockinfo      @kill_lock_spid bit=1, --是否杀掉死锁的进程,1 杀掉, 0 仅显示      @show_spid_if_nolock ...

  6. linux限定用户目录及权限

    setfacl -m u:username:rwx dir/file   -m:添加或者修改 u[设置用户]:username[用户名]:rwx[设置权限] g[设置组]:groupname[组名]: ...

  7. spring boot 中logback多环境配置

    spring boot 配置logback spring boot自带了log打印功能,使用的是Commons logging 具体可以参考spring boot log 因此,我们只需要在resou ...

  8. yii2高级模板安装

    通过 Composer 安装 如果还没有安装 Composer,在 Linux 和 Mac OS X 中可以运行如下命令: curl -sS https://getcomposer.org/insta ...

  9. Quartz教程:快速入门

    原文链接 | 译文链接 | 翻译:nkcoder | 校对:方腾飞 本系列教程由quartz-2.2.x官方文档翻译.整理而来,希望给同样对quartz感兴趣的朋友一些参考和帮助,有任何不当或错误之处 ...

  10. C++中几个值得分析的小问题(1)

    下面3个小问题都是我认为C++ Beginner应该能够解答或辨别清楚的.希望我们能通过题目挖掘更多的信息,而不仅仅局限在解题.我最喜欢说的话:能力有限,所以作为抛砖引玉,希望共同讨论,指出错误. 另 ...