警惕麦咖啡的"缓冲区溢出保护"引起的ASP.NET 中 System.OutOfMemoryException 的错误
客户服务器上的系统已经稳定运行好几年了,在客户更换过新服务器(双4核CPU,8G内存)一段时间后近期突然无法正常使用,打开首页或登录成功后,立即就出现 System.OutOfMemoryException 的错误,系统彻底崩了。
询问过谷哥和度娘后,得到的结论是:
按此方法,几经修改配置,仍无任何效果,于是进一步怀疑是各杀毒软捣的鬼,特别是麦咖啡的"缓冲区溢出保护",一看就是做内存访问限制的,于是第一个先将它停止,结果发现在将麦咖啡的"缓冲区溢出保护"停止后,系统恢复正常。但过几十秒钟后,又复崩溃。Why? 再检查麦咖啡,发现"缓冲区溢出保护"自动启动了......采用了N种方法将其停用无果,求助麦咖啡的客服无用,只能将麦咖啡从服务器上彻底删除,于是一切又恢复了正常。
最近进一步研究此问题,发现有这样的技术资料:
要解決這個問題的方式就是將 GC 設定為 Workstation Mode (工作站模式),這樣就可以整台主機共用同一個 GC Heap,以節省記憶體的使用。要將預設的 GC 修改成 Workstation Mode 必須要修改 %WINDIR%\Microsoft.NET\Framework\v2.0.50727\Aspnet.config 檔案 ( 如果是 .NET 1.1 要修改 %WINDIR%\Microsoft.NET\Framework\v1.1.4322\Aspnet.config 檔案 ):
默认的 Aspnet.config 長這樣:
<configuration>
<runtime>
<legacyUnhandledExceptionPolicy enabled="false" />
<legacyImpersonationPolicy enabled="true"/>
<alwaysFlowImpersonationPolicy enabled="false"/>
<SymbolReadingPolicy enabled="1" />
</runtime>
</configuration>
需加上一行 <gcServer enabled="false"/> 如下:
<configuration>
<runtime>
<gcServer enabled="false" />
<legacyUnhandledExceptionPolicy enabled="false" />
<legacyImpersonationPolicy enabled="true"/>
<alwaysFlowImpersonationPolicy enabled="false"/>
<SymbolReadingPolicy enabled="1" />
</runtime>
</configuration>
不过像这种出現 Out of Memory 的异常状况在 64 位位的操作系统几乎不会出现问题,所以如果你是用 64 位的操作系统(如:Windows Server 2003 64bit ) 的話,是不太需要做这样的调整的,但你的内存还是要够多才行,否则过多的分页況还是会降低你 ASP.NET 就用程序的执行效率!
除了这点之外,在正式(Production)环境中的 ASP.NET 应用程序一定要在 web.config 中关闭开发时期设定的 debug 与 trace,才不会内存造成额外的负担。因为 ASP.NET应用程序在启用debug mode 的时候所有的 Symbol 档(*.pdb)都会被载入内存中,不但会消耗不少内存,也会降低执行效率。