关于32位程序申请大内存问题(1.6G). 我在win7 64系统上面测试
Visual studio 10
int* Test=new int[1024*1024*200]; int* Test2=new int[1024*1024*200];
Microsoft C++ 异常: 内存位置 0x0044f660 处的 std::bad_alloc。
这只是一个简单的测试 . 我做三维仿真.. 内存要用到2G-4G左右.. 如何在64位系统 32位程序申请到大内存啊..
【成都IT培训】32位模式下C/C++程序到底可以用多少内存
32 位的程序寻址空间是 4G,因此能用的内存应该有 4G,除掉一些系统等使用的乱七八糟的东西,3G 内存应该没有问题吧,这些只是猜测,写个程序测一下,结果如下:
测试结论:
1. 栈内存最大可用 768k 左右;
2. 堆内存最大可用 1.586G 左右。
结果令人沮丧,才 1.6 G!!!
测试环境:Windows7 2G、IBMSL300、VC9
附录测试程序等
测试程序只考虑 windows,首先,说明一下相关知识:
内存可以来自两个地方,在栈空间上分配的内存(栈内存)和在堆空间分配的内存(堆内存)。
栈内存,通过 alloca 来申请。
堆内存,通过 malloc、new、VirtualAlloc 来申请。
测试程序如下:【成都IT培训】
发表于 2008-1-10 10:28 | 来自 51CTO网页
[只看他] 楼主
作者: eaglet
2008 年我写过一篇博客叫 《让.Net 应用程序突破2G的内存访问限制》这篇博客主要讲述了如何在32位操作系统下利用AWE 扩展访问超过2G的内存。AWE方式虽然可以访问超过2G的内存,但其本身也有一些问题,首先必须要锁定内存,其次需要自己写内存管理程序来管理这些内存,.net framework 无法在AWE 扩展的内存中创建托管堆。其实很多应用只是想申请比2G稍多一些的内存,最简单的方法还是采用/3GB开关来实现。本文将讲述如何利用 /3GB开关来让32位操作系统下.net 应用程序申请超过2GB的内存。
首先简单说一下这个 /3GB 开关 (知道的可以不看)
默认情况下,Windows 可以对总计 4 千兆字节 (GB) 的虚拟地址空间进行寻址。默认情况下,此地址空间中的 2 GB 为内核(操作系统)保留,另外 2 GB 是为用户模式程序保留的。当你将 /3GB 开关放入操作系统的 Boot.ini 文件中时,你就重新分配了虚拟地址空间,给用户模式程序提供 3 GB 的空间,同时将内核限制为 1 GB。
设置办法:C:\boot.ini 文件做如下修改:
[boot loader] timeout=30 default=multi(0)disk(0)rdisk(0)partition(2)\WINNT [operating systems] multi(0)disk(0)rdisk(0)partition(2)\WINNT="????" /3GB
如下操作系统可以支持 /3GB 开关
Windows XP Professional
Windows Server 2003
Windows Server 2003, Enterprise Edition
Windows Server 2003, Datacenter Edition
Windows 2000 Advanced Server
Windows 2000 Datacenter Server
Windows NT Server 4.0, Enterprise Edition
Windows VISTA , Windows 7 和 Windows server 2008 也支持这个开关
详见
http://www.microsoft.com/whdc/system/platform/server/PAE/PAEmem.mspx
设置完后重新启动系统,这时应用程序就可以申请超过3G的内存了。一切好像到这里就该结束了,然而并非如此。
当我运行我在.net framework 下做的测试程序时,我发现3GB开关打开后,这个测试程序依然无法申请超过2G的内存,内存申请到1.5G以上时就无法再分配内存了。
查找资料后我发现,操作系统在支持/3GB参数后应用程序也要做相应的修改,告诉操作系统可以按照/3GB方式运行才行,我想这很可能是出于对应用程序兼容性方面的考虑。
为了告知操作系统这个应用程序可以支持/3GB方式,我们需要往exe 文件头中添加一个 IMAGE_FILE_LARGE_ADDRESS_AWARE
标志。添加的方式很简单:
在你的系统的 Program Files\Microsoft Visual Studio 8\VC\bin 目录下找到 editbin
这个可执行文件,在命令行下执行:
editbin
/LARGEADDRESSAWARE yourapplication.exe 这里的yourapplication.exe 需要输入的是你的.net 应用程序的路径名加文件名。
执行了这条语句后,我再次运行测试程序,内存可以申请到 2.5G了,比2GB模式下多了1G内存可以使用。
最后多罗嗦一句,为什么.net 应用程序在 2GB 情况下只能申请最多 1.4-1.6 GB 的内存?
这是因为.net 的垃圾回收器在工作时需要拷贝 live objects,.net framework 需要为它保留一定空间的内存来完成这些拷贝工作。这也是为什么Microsoft 建议asp.net 应用程序内存分配的上限最好设置为800M的原因.
.net 应用程序如何优化性能,参见下面链接,大家有兴趣可以去看看,这里不再多说了,离主题有点远了。
Improving .NET Application Performance and Scalability
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4G内存的**——如何使用4GB(开启3GB和PAE)
Windows Vista是一款相当耗费资源的操作系统,特别是内存。要提升系统性能,最简单也最有效的方式是为系统扩充尽可能多的内存,windows 7当然也不例外,虽然不像vista那么耗资源。现如今内存已是大白菜,4G及以上内存必定是趋势。windows 7最高能支持多少物理内存呢? 我们先来看看vista:
根据微软给出的规格,除Starter版仅支持1GB内存外,其他版本的Windows Vista(32位)均能够支持4GB的“内存”——当然,指32位x86系统。需要注意的是,这里所谓的“4GB”并非等同于真正的物理内存,而是指可用的内存寻址空间。
对32位系统而言,4GB是其能够寻址空间的极限,除非通过PAE(Physical Address Extension 物理地址扩展)将4GB之上的内存通过映射的方式作为4GB空间中的页面来扩展。而在这4GB的地址空间中,必须为计算机的系统资源如BIOS、显卡、PCI-Express等PCI接口留出位置。
系统所支持的4GB寻址空间都包括哪些:首先,BIOS至少要占去512KB或者1MB,显卡要占去略大于其视频RAM的空间,比如说,对于在高分辩率下使用Aero Glass的情况而言,256MB显存是必需的,这就必须在4GB的寻址空间中为显卡的256MB视频RAM留出位置;第三,对基于x86的计算机系统而言,其还必须为其他的PCI设备保留相当部分的寻址空间,比如各种IO设备等。这样,系统在寻址真正的物理内存之前,系统中已经被各种资源占用512MB到1GB的寻址空间,也即是说,系统真正能够使用的物理内存大致在3 GB到3.4 GB之间。
这对于象Win7这样一款以1GB RAM越跳的系统而言,系统内存的可扩充空间实在太小,尤其与当年Windows XP 128MB-4GB的内存范围相比。而且,虽然Win7 X86从内核上来说应该是能够支持PAE的。当然,也需要硬件厂商特别是CPU、芯片组与主板厂商的配合。
另一方面,在32位的Windows系统——不仅仅Windows Vista / Win7中,所支持的4GB寻址空间被分成两部分:其中2GB可被应用程序使用,而另外的2GB则被系统内核占用。因此,即使对于系统中安装了4GB内存的Win7而言,应用程序所能够使用的内存也被限制在2GB之内,从而在某些情况下仍难免会出现“内存不足”的情况。对此,server用户虽然可以通过微软的4GT RAM Tuning来将内核的内存起始位置移至3GB处——以在Boot.ini中添加“/3GB”开关实现,即将为内核分配的虚拟地址空间缩小到1GB,而将应用程序可使用的地址空间扩展到3GB——但距理想程度仍有距离。
当然,如果64位,问题就好办多了,Windows Vista x64可支持的内存从8GB(Windows Vista Home Basic)到128GB(Windows Vista Ultimate),Win7也一样,类似的寻址限制不复存在。但在软件和游戏上,64位的用户要期望更多的软件和游戏厂家的支持。
附:Vista / windows 7如何开启PAE
1进入cmd:点击开始菜单,在搜索框中输入”cmd“,按下 Ctrl + Shift + Enter (进入cmd的管理员模式)
2输入如下命令BCDEdit /set PAE forceenable Windows 这里的BCDEdit是关于命令行的启动配置编辑器。使用上面的命令,你能启用物理地址扩展(PAE),让支持的内存大于4GB
Vista / windows 7开启3GB
因为32位windows默认应用程序只能使用2G内存,剩下的都保留给系统内核了,所以还要开启3GB
1进入cmd:点击开始菜单,在搜索框中输入”cmd“,按下 Ctrl + Shift + Enter (进入cmd的管理员模式)
2,输入如下命令bcdedit /set increaseuserva 3072 来使得windows把2G以上的内存也分配给应用程序!
补充XP和 2003 的开启方法:
1.打开 Windows 资源管理器。
2.在“工具”菜单上,单击“文件夹选项”。
3.在“查看”选项卡上,单击“显示所有文件和文件夹”,清除“隐藏受保护的操作系统文件”复选框,然后单击“确定”。如果显示警告对话框,单击“是”以继续。
4.在根文件夹(如 C:)下查找 Boot.ini 文件并删除它的只读属性。
5.打开 Boot.ini 文件,然后将 /PAE 参数添加到 ARC 路径中,如以下 Windows Server 2003 Datacenter Edition 示例所示:
multi(0)disk(0)rdisk(0)partition(2)\%systemroot%="Windows Server 2003, Datacenter Edition" /PAE
以xp为例,修改页面Boot.ini文件如下:
timeout=30
default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS
[operating systems]
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional" /noexecute=optin /fastdetect /PAE
6.在“文件”菜单上,单击“保存”。
7.还原 Boot.ini 文件的只读属性。
8.为使更改生效,请重新启动计算机。
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
一是为不同的平台生成不同的包。无论采取上面何种部署方式,Visual Studio都支持32位与64位的平台,而且用户还可以选择“任何CPU”,来提高应用程序包的兼容性。不过这不是最佳的选择。通常情况下,一些比较有经验的程序开发人员都会建议大家为不同的平台生成不同的应用程序包。如现在有个应用程序需要分别发布到32位与64位两种平台上,此时最好生成两个MSI包,分别用于32位计算机与64位计算机平台上。如此的话,可以避免因为混合代码而造成的稳定性与性能方面的一些负面影响。