.NET拥有自己的内存回收机制,大大方便了我们的开发。但并不意味着内存的问题从此一劳永逸了。在开发时,我们依然会遇到各种各样的内存故障。
内存溢出是最常见的内存故障,在解析内存为什么会溢出之前,我们先了解一下WIN32的内存模式:
WIN32内存模式分为系统模式和用户模式,各占2GB的寻址空间。对于任何一个进程而言,理论上都有4GB的内存寻址空间。其中开头的4M和结尾的2GB被系统核心占用,剩下的不到2GB寻址空间是我们的应用程序可以访问的。因此程序内存溢出,我们首先应该检查是否超出了自己的寻址空间。
对于.NET程序而言,会因为framework以及各种程序集消耗很多内存,因此.NET程序真正可用的寻址空间将远远小于2GB。当应用程序消耗的内存超过特定的限额时(通常在1.2GB左右),framework就会抛出System.OutOfMemoryException。由于.NET采用非实时内存垃圾回收的机制,那么对于一个.NET程序而言,在进行垃圾回收之前,内存只减不增,消耗极快,这又进一步促使内存溢出故障的发生。
以上就是绝大部分内存溢出的原因。
我们可以采取一些手段来规避这个问题:
1. 从核心系统索取更多的寻址空间
在Windows2000、Windows XP以及Windows 2003中,我们都可以通过设置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
然后,我们需要对exe文件连接LARGEADDRESSAWARE选项来支持大寻址空间模式:
link -edit -LARGEADDRESSAWARE app.exe
如此一番操作之后,我们的应用程序就可以使用更大的内存空间了(大概2.4GB左右)。
注意:需要使用管理员身份调用程序。
2. 使用AWE
3GB内存地址空间只是微软的一个应急解决方案,如果我们的程序跑在拥有4GB或者更大内存的服务器上面时,我们应当尝试使用AWE来实现对2GB以外内存地址空间的访问。不过我在这块也是一知半解,网上有相当多关于AWE的资料,搜索一下就行了。