1 问题描述
目前公司的很多程序需要在32位模式下运行,有些项目的相关系统容易遇到内存溢出的问题,系统在使用过程中不太稳定。通过分析得出,默认情况下,32程序的内存地址空间只有2G,这2G内存除了存储程序数据外还需要存储程序本身,根据经验,程序一旦使用超过1G的内存就不太稳定。
2 解决方案
2.1 方案一:进程拆分
将程序中耗内存的功能拆分成单独的进程。此方法在目前的各个项目开发中正在使用。但有时候会出现功能无法拆分(如数据浏览),或拆分后还出现主进程较长时间使用还是出现内存溢出的问题。所以此方案还不能完全解决这个内存溢出的问题。
2.2 方案二:突破2G限制
通过开启/largeaddressaware 的方式突破单进程2个G的限制(理论最大4G 虚拟地址空间)。
2.2.1 操作方法
具体操作方法:
方法1:在命令行依次执行以下几行命令
cd C:\Program Files(x86)\Microsoft Visual Studio 11.0\VC\bin
vcvars32.bat
editbin /largeaddressawrexx.exe
方法2:在VS (以VS2012为例)项目属性->生成事件->后期生成事件命令行中设置如下命令行:
call"%VS110COMNTOOLS%..\tools\vsvars32.bat"
editbin /largeaddressaware$(TargetPath)
说明:方法一在每次编译后需要执行相关命令;方法二在VS编译后自动完成相关设置操作,使用方便。
2.2.2 测试程序
以下为测试程序的编写示例:
测试程序:通过在exe中进行编写以下大量分配内存的程序进行测试,将错误信息输出到日志
static void Main(string[] args)
{
try
{
int count = 100000000;
List<int[]> lst = newList<int[]>(count);
for (int i = 0; i < count;i++)
{
lst.Add(new int[1000000]);
}
}
catch (Exception ex)
{
LogHelper.Error.Append(ex);
}
}
1)未突破2G限制的日志信息如下:
19:33:07:849
System.OutOfMemoryException:引发类型为“System.OutOfMemoryException”的异常。
19:33:07:855
当前专用内大小:1.69 GB
当前虚拟内存大小:1.94 GB
最大虚拟内存量:1.94 GB
物理内存总大小:4 GB
可用物理内存大小:4 GB
虚拟内存总大小:2 GB
可用虚拟内存大小:62.31 MB
交换空间总大小:4 GB
可用交换空间大小:4 GB
2)突破4G限制的日志信息如下:
19:33:45:371
System.OutOfMemoryException:引发类型为“System.OutOfMemoryException”的异常。
19:33:45:377
当前专用内大小:3.59 GB
当前虚拟内存大小:3.9 GB
最大虚拟内存量:3.91 GB
物理内存总大小:4 GB
可用物理内存大小:4 GB
虚拟内存总大小:4 GB
可用虚拟内存大小:105.38 MB
交换空间总大小:4 GB
可用交换空间大小:4 GB
2.3 结论
综上,通过方案一和方案二相结合,能比较完美地解决32位程序内存溢出的问题(当然,如果这个程序使用过程中占用的内存达到3G以上的时候还是容易出问题,那就需要从程序本身去优化了)。
3 参考资料
一个进程所能分配的最大内存是多大?这是由什么决定的?:
https://www.zhihu.com/question/29468200?sort=created
c#程序内存分配:
http://www.cnblogs.com/Leo_wl/p/5382033.html
C# .Net 下 x86使用大内存的处理:
http://www.cnblogs.com/xidongs/p/3806378.html
C# 开启大地址内存以应对32位机器内存不够用问题:
http://blog.csdn.net/chuiwenwei_csdn/article/details/51131360
C# .Net 下 x86使用大内存的处理:
http://www.cnblogs.com/xidongs/p/3806378.html
研究C#对象所占内存的大小,以及count与capacity的区别:
http://blog.sina.com.cn/s/blog_60c2e6ad0102wae9.html
https://stackoverflow.com/questions/2597790/can-i-set-largeaddressaware-from-within-visual-studio/3963184