zoukankan      html  css  js  c++  java
  • 发现并解决ASP.NET内存耗尽(OOM),让服务器"永不重启"

    ========下面的一堆文字为了说明一件事情---.NET程序,内存溢出,如何控制.主要是堆HEAP大小如何控制以及优化.以减轻GC突发性负担及这个时候服务器当机的可能*.
    对于大型程序,完全依赖GC是不现实的,对于高负载服务器,往往我们80%的堆都由自己的析构函数接管,并辅助以自行设计的bufferpool接管堆释放工作以达到HEAP可控的目的,减少CPU突发性负荷(CPU尖峰).虽然不像C那样可以控制的那么完全,但是多多少少对OOM的发生起到抑制作用,深入下去可以完全避免OOM......好了IF性能和内存开销没什么追求的 THEN 就不必看了,,,,

    ELSE

    GO

    =====================
    1.下个windbg,去baidu google一下即可..
    2.sos.dll 这个框架自带,只所以提下,是让大家有搜索的关键字用.
    3.泄露,对于.net程序,主要是堆泄露,对于大型服务器程序,需要严格排查OOM(内存泄露)的问题,节约服务器GC开销,内存开销,cpu开销,提高支撑
    4.配置环境变量 添加系统变量 _NT_DEBUGGER_EXTENSION_PATH   C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727  这个是为了能够找到sos.dll
    5.实战
    启动windbg,开启调试窗口,加载用于.NET调试所使用的sos.dll
    .load sos
    回车之后无任何显示表示无任何错误,这个时候就可以运行调试命令了.
    需要说明的是.打头的是windbg自带命令,!打头的命令是sos.dll调试命令.

    显示GC堆占用情况命令  !dumpheap -stat
    大概会显示这些:对象表,对象数量,每个对象内存占用情况...等,如下:
    ---------------------
    0:000> !dumpheap -stat
    Statistics:
    MT             Count       TotalSize Class Name
    7a787cc4           1              12 System.IO.FileSystemWatcher+FSWAsyncResult
    7a75904c           1              12 System.Diagnostics.OrdinalCaseInsensitiveComparer
    7a7575cc           1              12 System.CodeDom.Compiler.CodeDomConfigurationHandler
    7a7571a8           1              12 System.Net.DefaultCertPolicy
    7a75661c           1              12 System.Diagnostics.TraceListenerCollection
    7a755834           1              12 System.Diagnostics.PerformanceCounterCategoryType
    ..................
    68a66a88     227,559      12,743,304 System.Web.UI.WebControls.Literal
    68a2f7fc     399,272      14,373,792 System.Web.UI.ControlCollection
    68a92e2c     768,731      33,824,164 System.Web.UI.Control+OccasionalFields
    68a884a0     641,952      38,517,120 System.Web.UI.LiteralControl
    79124228     879,515      43,394,976 System.Object[]
    790fa3e0   1,431,594     122,806,484 System.String



    Total 10,389,625 objects, Total size: 463,313,540
    ----------------------



    1,431,594 个 System.String对象 占用 122 MBytes




    使用!dumpobj 可以查看System.String对象构成情况

    0:000> !dumpheap -type System.Web.UI.LiteralControl
     Address       MT Size Gen
    023ea0a8 68a884a0   60   2 System.Web.UI.LiteralControl
    023ea0e4 68a884a0   60   2 System.Web.UI.LiteralControl
    023ea374 68a884a0   60   2 System.Web.UI.LiteralControl
    023ea460 68a884a0   60   2 System.Web.UI.LiteralControl
    023ea510 68a884a0   60   2 System.Web.UI.LiteralControl
    023eab3c 68a884a0   60   2 System.Web.UI.LiteralControl
    ........CONTINUED........
    023fe31c 68a884a0   60   2 System.Web.UI.LiteralControl
    023fe414 68a884a0   60   2 System.Web.UI.LiteralControl
    023fe4c4 68a884a0   60   2 System.Web.UI.LiteralControl
    023fe500 68a884a0   60   2 System.Web.UI.LiteralControl

    哦 基本上都是LiteralControl

    随便抓个控件的地址来分析!do命令

    0:000> !do 023ea0a8
    Name: System.Web.UI.LiteralControl
    MethodTable: 68a884a0
    EEClass: 68a88428
    Size: 60(0x3c) bytes
    GC Generation: 2
    (C:\WINDOWS\assembly\GAC_32\System.Web\2.0.0.0__b03f5f7f11d50a3a\System.Web.dll)
    Fields:
          MT    Field Offset                   Type   VT     Attr    Value Name
    790fa3e0  4001fe0      4          System.String    0 instance 00000000 _id
    790fa3e0  4001fe1      8          System.String    0 instance 00000000 _cachedUniqueID
    68a2af44  4001fe2      c   ...em.Web.UI.Control    0 instance 023e8864 _parent
    68a91070  4001fe3     2c           System.Int32    0 instance        0 _controlState
    68a85ea0  4001fe4     10   ...m.Web.UI.StateBag    0 instance 00000000 _viewState
    68a2af44  4001fe5     14   ...em.Web.UI.Control    0 instance 023e8864 _namingContainer
    68a273d0  4001fe6     18     System.Web.UI.Page    0 instance 01df4514 _page
    68a92e2c  4001fe7     1c   ...+OccasionalFields    0 instance 00000000 _occasionalFields
    68a2b378  4001fe8     20   ...I.TemplateControl    0 instance 00000000 _templateControl
    68a14528  4001fe9     24   ...m.Web.VirtualPath    0 instance 00000000 _templateSourceVirtualDirectory
    68a8bb48  4001fea     28   ...rs.ControlAdapter    0 instance 00000000 _adapter
    68a3a8f8  4001feb     30   ...SimpleBitVector32    1 instance 023ea0d8 flags
    790f9c18  4001fda    c70          System.Object    0   shared   static EventDataBinding
    >> Domain:Value 000f0d00:NotInit 0011a720:01df0028 <<
    790f9c18  4001fdb    c74          System.Object    0   shared   static EventInit
    >> Domain:Value 000f0d00:NotInit 0011a720:01df0034 <<
    790f9c18  4001fdc    c78          System.Object    0   shared   static EventLoad
    >> Domain:Value 000f0d00:NotInit 0011a720:01df0040 <<
    790f9c18  4001fdd    c7c          System.Object    0   shared   static EventUnload
    >> Domain:Value 000f0d00:NotInit 0011a720:01df004c <<
    790f9c18  4001fde    c80          System.Object    0   shared   static EventPreRender
    >> Domain:Value 000f0d00:NotInit 0011a720:01df0058 <<
    790f9c18  4001fdf    c84          System.Object    0   shared   static EventDisposed
    >> Domain:Value 000f0d00:NotInit 0011a720:01df0064 <<
    79124228  4001fec    c88        System.Object[]    0   shared   static automaticIDs
    >> Domain:Value 000f0d00:NotInit 0011a720:01df0070 <<
    790fa3e0  4002211     34          System.String    0 instance 02238664 _text

    这里如果发现某个值过大,就可以继续深入使用!do + 地址 来进入查看,以便找到OOM的根源..试试

    0:000> !do 02238664
    Name: System.String
    MethodTable: 790fa3e0
    EEClass: 790fa340
    Size: 158(0x9e) bytes
    GC Generation: 2
    (C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
    String:       
    Fields:
    MT Field Offset Type VT Attr Value Name
    790fed1c 4000096 4 System.Int32 0 instance 71 m_arrayLength
    790fed1c 4000097 8 System.Int32 0 instance 70 m_stringLength
    790fbefc 4000098 c System.Char 0 instance 3c m_firstChar
    790fa3e0 4000099 10 System.String 0 shared static Empty
    >> Domain:Value 000f0d00:790d6584 0011a720:790d6584 <<
    79124670 400009a 14 System.Char[] 0 shared static WhitespaceChars
    >> Domain:Value 000f0d00:01d413b8 0011a720:01d44f80 <<

    可以看到32位地址为02238664的是用于表格的结束标志存储.

    使用!objsize进一步命令查看对象内的的对象构成,精确到class名,自己可以试试了...还有很多命令可以查看Gen的回收情况,对于长时间未释放的unmanaged资源也可以列表出来,这个时候可以do进去,查看内部结构,找到属于哪段代码之后,再返回自己的.cs代码进行逻辑调整....这样的话,性能就很可观了.同时可以尽量使用好CPU,而不必让不必要的CPU时间牺牲框架和底层的代码胶合层上面..永远要记住CPU时间是用户的,不是你的!这样,对内存了解的多一些,你的程序就能跑的更快一点,持久运行的时间就更长一些...

    通常,asp.net或者socket服务器运行的时候,对内存的要求是比较高的,如果内存的性能我们不能去把握,真的很难再生产环境中超越LAMP体系架构.
    我的观点是,内存---能节约,尽量节约吧,能高效利用,尽量高效利用!所以写这篇帖子,非常非常肤浅的介绍了下,前后也就写了20分钟,因为要睡觉了...

    来源:http://www.cnblogs.com/koumi/archive/2010/10/12/1849077.html

  • 相关阅读:
    运输装备(codevs 1669)
    考前复习(codevs 2837)
    2014编程之美初赛第一场
    51系列小型操作系统精髓 简单实现
    数学----有趣的扑克牌《一》
    hadoop编程:分析CSDN注冊邮箱分布情况
    [动态规划]UVA437
    Swift学习笔记四:数组和字典
    [动态规划]UVA10285
    freemarker中的left_pad和right_pad
  • 原文地址:https://www.cnblogs.com/luluping/p/1849772.html
Copyright © 2011-2022 走看看