zoukankan      html  css  js  c++  java
  • 警惕麦咖啡的"缓冲区溢出保护"引起的ASP.NET 中 System.OutOfMemoryException 的错误

       客户服务器上的系统已经稳定运行好几年了,在客户更换过新服务器(双4核CPU,8G内存)一段时间后近期突然无法正常使用,打开首页或登录成功后,立即就出现 System.OutOfMemoryException 的错误,系统彻底崩了。

       询问过谷哥和度娘后,得到的结论是:

    在ASP.NET Web(U8Soft.AppServer)服务器上,ASP.NET所能够用到的内存,通常不会等同于所有的内存数量。在machine.config配置文件(目录)中,配置节中有一个属性“memoryLimit”,这个属性的值是一个百分值,默认为“60”,即指定了ASP.NET进程(在任务管理器中大家就可以看到ASP.NET的进程,IIS5中为aspnet_wp,IIS6中为w3wp)能够使用所有物理内存的60%。当ASP.NET使用的内存量超过这个限额时,IIS会开始自动回收(recycle)进程,即创建一个新的进程去负责应付Http请求,而将旧进程所占用的内存回收。 ??当我们有一台很大内存的服务器时,“memoryLimit”这个值是需要进行适当的调整的。比如我们准备了一台4G内存的服务器,那么4G×60%=2.4G。但是,对于Win32操作系统,一个进程所能占用的所有内存空间只有2G。当ASP.NET进程占用的内存开始达到2G时,由于它并没有达到2.4G的“回收阈值”,所以IIS不会启动recycle进程操作,但是由于Win32的限制,实际上已经不能给这个进程分配更多的内存了,于是,OutOfMemoryException就很可能会被抛出了。为了避免这样的情况,我们就必须将“memoryLimit”适当调小,以让IIS更早的进行进程回收。 ??微软推荐的ASP.NET进程占用内存是不超过60%,并最好使计算出的实际值不超过800M。就是说,对于一台4G内存的服务器,最好将“memoryLimit”属性设置成“20”。设置一个适当的回收阈值,让IIS适时的进行进程回收,对于保证整个服务器的稳定运行,避免OutOfMemoryException是非常重要的。 ??在IIS6中,ASP.NET进程的回收阈值不再由配置节中的“memoryLimit”属性决定,而是由IIS管理器中的应用程序池配置中的设置决定。 ??但是,即使正确设置了这些配置,也不能保证完全避免OutOfMemoryException的发生,原因可能是多样而复杂的,比如内存回收操作可能耗时太多等等。开发人员要注意的,就是在代码中时刻牢记不要无谓的使用和浪费内存。

      按此方法,几经修改配置,仍无任何效果,于是进一步怀疑是各杀毒软捣的鬼,特别是麦咖啡的"缓冲区溢出保护",一看就是做内存访问限制的,于是第一个先将它停止,结果发现在将麦咖啡的"缓冲区溢出保护"停止后,系统恢复正常。但过几十秒钟后,又复崩溃。Why? 再检查麦咖啡,发现"缓冲区溢出保护"自动启动了......采用了N种方法将其停用无果,求助麦咖啡的客服无用,只能将麦咖啡从服务器上彻底删除,于是一切又恢复了正常。

         

         最近进一步研究此问题,发现有这样的技术资料:

    多處理器(或多核心)電腦上的 .NET CLR 的 Garbage Collection (GC) 機制預設是使用 Server Mode (伺服器模式) 在運作的,換句話說,就是「每一顆 CPU 都會有獨立的 GC 記憶體空間(堆積, Heap)」,所以如果你的 GC 記憶體空間 用掉了 500MB 且你有 4 顆 CPU 的話,就等於耗費了 2GB 的記憶體,進而發生 System.OutOfMemoryException 例外狀況!

    要解決這個問題的方式就是將 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 長這樣:

    <?xml version="1.0" encoding="UTF-8" ?>
    <configuration>
        <runtime>
            <legacyUnhandledExceptionPolicy enabled=
    "false" />
            <legacyImpersonationPolicy enabled=
    "true"/>
            <alwaysFlowImpersonationPolicy enabled=
    "false"/>
            <SymbolReadingPolicy enabled=
    "1" />
        </runtime>
    </configuration>

    需加上一行 <gcServer enabled="false"/> 如下:

    <?xml version="1.0" encoding="UTF-8" ?>
    <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)都会被载入内存中,不但会消耗不少内存,也会降低执行效率。

  • 相关阅读:
    HDU 5835 Danganronpa 贪心
    HDU 5842 Lweb and String 水题
    HDU 5832 A water problem 水题
    Codeforces Beta Round #14 (Div. 2) A. Letter 水题
    Western Subregional of NEERC, Minsk, Wednesday, November 4, 2015 Problem K. UTF-8 Decoder 模拟题
    Western Subregional of NEERC, Minsk, Wednesday, November 4, 2015 Problem I. Alien Rectangles 数学
    Western Subregional of NEERC, Minsk, Wednesday, November 4, 2015 Problem H. Parallel Worlds 计算几何
    Western Subregional of NEERC, Minsk, Wednesday, November 4, 2015 Problem F. Turning Grille 暴力
    Western Subregional of NEERC, Minsk, Wednesday, November 4, 2015 Problem C. Cargo Transportation 暴力
    Western Subregional of NEERC, Minsk, Wednesday, November 4, 2015 Problem G. k-palindrome dp
  • 原文地址:https://www.cnblogs.com/techrich/p/2115888.html
Copyright © 2011-2022 走看看